V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
mytry
V2EX  ›  程序员

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

  •  
  •   mytry · May 29, 2019 · 6188 views
    This topic created in 2533 days ago, the information mentioned may be changed or developed.

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

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

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

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

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

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

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

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

    正经答案:不要尝试诡异的方法,让用户改变执行方式。
    PTLin
        16
    PTLin  
       May 29, 2019
    @PTLin 记错了,不是把一个管道 dup 到多个进程上,是对应子进程开多个 pipe 来分别写入
    zwh2698
        17
    zwh2698  
       May 30, 2019 via Android
    用管道执行,就可以通过管道获取 ,linux 和 windows 都可以,只是 API 不同
    zwh2698
        18
    zwh2698  
       May 30, 2019 via Android
    是不是我看错题了,如果错了,请忽略
    zwh2698
        19
    zwh2698  
       May 30, 2019 via Android
    没懂你的问题
    trn4
        20
    trn4  
       May 30, 2019
    curl 一个脚本,在脚本里下载你的脚本。直接执行怕是不行,curl+pipe 中间根本就没有文件,何来路径。
    pkookp8
        21
    pkookp8  
       May 30, 2019 via Android
    自己做一个 shell
    ihipop
        22
    ihipop  
       May 30, 2019 via Android
    @ipwx 你这太麻烦了。中间管道换成 tee 就行了
    zerofiny
        23
    zerofiny  
       May 30, 2019
    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  
       Jul 9, 2019
    quine?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2905 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 284ms · UTC 09:15 · PVG 17:15 · LAX 02:15 · JFK 05:15
    ♥ Do have faith in what you're doing.