将wget输出(流式shell脚本)传递给bash,但带有额外的参数

时间:2017-05-20 05:55:32

标签: bash wget

我想通过wget下载特定文件,将其作为bash脚本传递,并一次性为其提供参数。

就我而言,脚本存储在:https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh

我试过了:

wget -O - https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh | bash

但结尾于:

Error: you need to provide a host and port to test.
Usage:
    bash host:port [-s] [-t timeout] [-- command args]
    -h HOST | --host=HOST       Host or IP under test
    -p PORT | --port=PORT       TCP port under test
                            Alternatively, you specify the host and port as host:port
    -s | --strict               Only execute subcommand if the test succeeds
    -q | --quiet                Don't output any status messages
    -t TIMEOUT | --timeout=TIMEOUT
                            Timeout in seconds, zero for no timeout
    -- COMMAND ARGS             Execute command with args after the test finishes

因为我还需要将参数传递给此bash脚本(主机名端口以检查我的具体情况),即我需要运行类似的东西:

wait-for-it.sh localhost:8181

更新 我很乐意在没有本地保存的情况下获得解决方案(=>只需要管道bash

1 个答案:

答案 0 :(得分:4)

对于递归的脚本,这很简单:

 # pipe source code to `bash`, run code with args *foo* and *bar*
 <stream with source code> | bash -s - foo bar 

但是脚本wait-for-it.sh包含$0,并且有点递归,(它调用自身),这使得它与流不兼容,因为:

  1. 该流没有随机访问寻求工作的文件名,
  2. 无法将$0更改为信息流的名称。
  3. bash管道功能绕过:

    strm2fnct(){ 
    s=${1:-self$$}
    sed "1i $s"'() {
    s/\$0/'"$s"'/
    /timeout/{s/'"$s"'[^&]*/bash -c "&" /};
    $a \} ; export -f '"$s; $s"' "$@"'
    }
    

    此问题的用法:

    f='https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh'
    wget -O - "$f" | strm2fnct ${f##*/} | bash -s - 'localhost:8181'
    

    输出:

    --2017-05-21 21:21:49--  https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh
    Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.36.133
    Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.36.133|:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 4070 (4.0K) [text/plain]
    Saving to: ‘STDOUT’
    
    -   100%[===========================================>]   3.97K  --.-KB/s    in 0.1s    
    
    2017-05-21 21:21:50 (29.8 KB/s) - written to stdout [4070/4070]
    
    wait-for-it.sh: waiting 15 seconds for localhost:8181
    wait-for-it.sh: timeout occurred after waiting 15 seconds for localhost:8181
    

    方式。

    虽然bash不会保存流数据,但它会记住功能。因此strm2fnct

    • 将整个流(注释和所有内容)包装在 ad hoc 中 壳功能;例如:

      strm2fnct <<< "echo hello world"
      

      输出:

      self6196() {
      echo hello world
      } ; export -f self6196; self6196 "$@"
      
    • 这个 ad hoc 函数默认获得一个准随机名称,(实际上它是字符串&#34; self &#34 ;后跟 PID ),或者可以传递一个名称,例如 strm2fnct foobar命名 ad hoc 函数{{1 }};

    • 使用 ad hoc 名称替换foobar()的每个实例,但是......
    • $0中的timeout个命令需要进一步执行 编辑:

      wait-for-it.sh

      ...因为grep -n '^ *timeout' wait-for-it.sh 56: timeout $BUSYTIMEFLAG $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & 58: timeout $BUSYTIMEFLAG $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & 无法看到shell 函数,因此需要导出 ad hoc 函数,并由timeout调用,并且需要引用其参数。通过运行查看更改:

      bash -c