在执行curl提取的脚本时将参数传递给bash

Dan*_*l R 48 bash curl argument-passing

我知道如何通过以下语法执行远程bash脚本:

curl http://foo.com/script.sh | bash
Run Code Online (Sandbox Code Playgroud)

要么

bash < <( curl http://foo.com/script.sh )
Run Code Online (Sandbox Code Playgroud)

这给出了相同的结果.

但是如果我需要将参数传递给bash脚本呢?脚本在本地保存时可能:

./script.sh argument1 argument2
Run Code Online (Sandbox Code Playgroud)

我试过这样的几种可能性,没有成功:

bash < <( curl http://foo.com/script.sh ) argument1 argument2
Run Code Online (Sandbox Code Playgroud)

jin*_*ski 73

尝试

curl http://foo.com/script.sh | bash -s arg1 arg2
Run Code Online (Sandbox Code Playgroud)

bash手册说:

如果存在-s选项,或者在选项处理后没有参数,则从标准输入读取命令.此选项允许在调用交互式shell时设置位置参数.

  • 如果arg1是一个简短的arg,请不要工作:curl http://foo.com/script.sh | bash -s -y (4认同)
  • 谢谢 !非常有用的要点:) (3认同)
  • 使用诸如-p blah -d blah之类的键的参数呢? (3认同)
  • 这种方式直接忽略了脚本中的`read`,如何解决? (2认同)

Jan*_*erg 66

要改善jinowolski的答案,你应该使用:

curl http://example.com/script.sh | bash -s -- arg1 arg2
Run Code Online (Sandbox Code Playgroud)

注意两个破折号( - )告诉bash不要将其后面的任何内容作为bash的参数进行处理.

这样它就可以用于任何类型的参数,例如:

curl -L http://bootstrap.saltstack.org | bash -s -- -M -N stable
Run Code Online (Sandbox Code Playgroud)

这当然可以通过stdin进行任何类型的输入,而不仅仅是curl,所以你可以通过echo确认它是否适用于简单的BASH脚本输入:

echo 'i=1; for a in $@; do echo "$i = $a"; i=$((i+1)); done' | \
bash -s -- -a1 -a2 -a3 --long some_text
Run Code Online (Sandbox Code Playgroud)

会给你输出

1 = -a1
2 = -a2
3 = -a3
4 = --long
5 = some_text
Run Code Online (Sandbox Code Playgroud)

  • 为了额外的安全,建议使用 `curl --fail ...`。例如,它使 curl 在 404 上停止。一组常见的选项是`-fsSL`(`-f` 是`--fail` 的缩写)。 (2认同)

eph*_*ent 14

其他替代品:

curl http://foo.com/script.sh | bash /dev/stdin arguments
bash <( curl http://foo.com/script.sh ) arguments
Run Code Online (Sandbox Code Playgroud)

  • $ 0参数的所有方法都不同.对于"-s",它是"bash",对于"/ dev/stdin",它是"/ dev/stdin","<(...)"给出$ 0参数,如"/ dev/fd/63". (2认同)