V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
mytry
V2EX  ›  程序员

通过管道执行的脚本(例如 curl xxx.com | sh)有办法拿到当前脚本内容吗?

  •  
  •   mytry · 2019-05-29 16:43:50 +08:00 · 5671 次点击
    这是一个创建于 2035 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如果先下载到本地文件再执行,可以通过 $0 拿到当前脚本的路径,之后可以进行复制等操作。

    但通过例如 curl xxx.com | sh 这种方式执行,还能优雅拿到当前运行的脚本内容吗?重复 curl 一次不算,预先把整个脚本的内容当做字符串不算。

    最好有类似 JS 里可以把函数 toString 的方法,外表仍然是可执行的代码,但可以运行时转成字符串数据。不知道 shell 或 bash 里能否实现~

    第 1 条附言  ·  2019-05-30 08:25:30 +08:00
    看来还是脚本里重复 curl 一次比较简单和优雅~
    24 条回复    2019-07-09 12:24:05 +08:00
    c
        1
    c  
       2019-05-29 16:47:26 +08:00
    `tee`
    mytry
        2
    mytry  
    OP
       2019-05-29 16:50:11 +08:00
    @c 这个需要改变执行的命令了吧~ 能不改变执行命令,只在脚本里实现吗?
    v2nika
        3
    v2nika  
       2019-05-29 16:55:15 +08:00
    它本身就不是一个文件, 如果你要的是 $PWD + 你 curl 的 pathname 的最后一层, 那么通过 pipe 是不可能拿到的, 因为 pipe 只会管 stdout/stderr
    jswh
        4
    jswh  
       2019-05-29 17:03:04 +08:00
    可以用 exec 命令

    #!/bin/bash
    cmd='echo exec'
    echo $cmd
    exec $cmd
    ipwx
        5
    ipwx  
       2019-05-29 17:05:25 +08:00
    curl xxx | sh -c 'SCRIPT=/tmp/tmp.sh; cat > "$SCRIPT"; sh "$SCRIPT"'
    ipwx
        6
    ipwx  
       2019-05-29 17:06:14 +08:00
    哦我没读懂楼主的意思,抱歉。
    jswh
        7
    jswh  
       2019-05-29 17:09:41 +08:00
    @jswh 噢,不能直接当字符串
    BIAOXYZ
        8
    BIAOXYZ  
       2019-05-29 17:17:16 +08:00   ❤️ 1
    @c 这 ID 堪比四位数 QQ 了。。。
    qooweds
        9
    qooweds  
       2019-05-29 18:55:27 +08:00   ❤️ 1
    没太明白?打印执行内容吗?
    试试 set -x?
    ps1aniuge
        10
    ps1aniuge  
       2019-05-29 20:34:12 +08:00
    问:如何在 powershell.exe 中,边执行,边观看脚本调用过程,并显示变量值?类似于 sh -x 那样?
    答:
    1 在 powershell.exe 中敲入命令:(放在脚本的第一行也行,第 n 行也行,放哪就从哪显示)
    set-psdebug -Trace 2
    2 运行脚本。
    RobberPhex
        11
    RobberPhex  
       2019-05-29 21:48:07 +08:00
    bashdb?
    iwtbauh
        12
    iwtbauh  
       2019-05-29 22:48:02 +08:00 via Android
    看完评论又读了一遍题,答案是不能

    至少 POSIX shell 没有给脚本提供这种接口,但你可以制作一个“修改版本”的 shell 解释器,提供一些命令扩展,让 shell 读尽全部输入,并把新输入和执行过的代码以字符串形式暴露给当前执行的代码。
    msg7086
        13
    msg7086  
       2019-05-29 23:03:59 +08:00
    反过来想想,管道是个流,所以 sh 在执行到你代码的时候,文件可能还没读完呢。也就是说,最多最多,在你的 shell 脚本里只能读到这行代码之前的内容,而没办法读到之后的。

    至于能不能读,我觉得难。
    PTLin
        14
    PTLin  
       2019-05-29 23:08:46 +08:00
    有一个叫 moreutils 的包里面提供了一个叫 pee 的程序来把管道的读端 dup 到多个子进程上,这样你就可以用 curl xxx.com | pee "cat >foo.sh" sh,既能把脚本输出到文件,同时又能执行脚本。
    geelaw
        15
    geelaw  
       2019-05-29 23:22:57 +08:00 via iPhone
    听起来是说楼主有一个脚本要通过网络分发并且用这种方式执行,又希望自己的脚本可以知道自己的代码。

    这很简单,既然楼主自己可以控制代码,那么用递归定理改变脚本的写法即可,这样脚本可以自己算出自己的代码。

    正经答案:不要尝试诡异的方法,让用户改变执行方式。
    PTLin
        16
    PTLin  
       2019-05-29 23:23:38 +08:00
    @PTLin 记错了,不是把一个管道 dup 到多个进程上,是对应子进程开多个 pipe 来分别写入
    zwh2698
        17
    zwh2698  
       2019-05-30 00:06:29 +08:00 via Android
    用管道执行,就可以通过管道获取 ,linux 和 windows 都可以,只是 API 不同
    zwh2698
        18
    zwh2698  
       2019-05-30 00:07:40 +08:00 via Android
    是不是我看错题了,如果错了,请忽略
    zwh2698
        19
    zwh2698  
       2019-05-30 00:08:18 +08:00 via Android
    没懂你的问题
    xiadong1994
        20
    xiadong1994  
       2019-05-30 00:41:20 +08:00
    curl 一个脚本,在脚本里下载你的脚本。直接执行怕是不行,curl+pipe 中间根本就没有文件,何来路径。
    pkookp8
        21
    pkookp8  
       2019-05-30 01:17:42 +08:00 via Android
    自己做一个 shell
    ihipop
        22
    ihipop  
       2019-05-30 08:50:57 +08:00 via Android
    @ipwx 你这太麻烦了。中间管道换成 tee 就行了
    hasdream
        23
    hasdream  
       2019-05-30 10:04:35 +08:00
    curl ww.a.com/a.sh | python -c 'import sys;stdin=sys.stdin.read();f=open("/tmp/a.sh", "w");f.write(stdin);f.flush();sys.stdout.write(stdin);sys.stdout.flush()' | sh
    no1xsyzy
        24
    no1xsyzy  
       2019-07-09 12:24:05 +08:00
    quine?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3023 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 13:55 · PVG 21:55 · LAX 05:55 · JFK 08:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.