我有一个简单的Bash脚本:
#!/usr/bin/env bash
read X
echo "X=$X"
当我使用./myscript.sh
执行它时,它可以工作。但是当我使用cat myscript.sh | bash
执行它时,实际上会将echo "X=$X"
放入$X
。
因此,此脚本会打印使用cat myscript.sh | bash
执行的 Hello World :
#!/usr/bin/env bash
read X
hello world
echo "$X"
cat myscript.sh | bash
执行脚本有什么好处?为什么不这样做就像我用./myscript.sh
执行它一样?答案 0 :(得分:7)
而不是仅仅运行
read X
...而是将其替换为......
read X </dev/tty || {
X="some default because we can't read from the TTY here"
}
...如果你想从控制台读取。当然,这仅在 一个/dev/tty
时有效,但如果你想做一些健壮的事情,你就不会从curl
进入shell。 :)
另一种选择当然是在命令行传递X
的值。
curl https://some.place/with-untrusted-code-only-idiots-will-run-without-reading \
| bash -s "value of X here"
...如果需要"$1"
,请参阅脚本中的X
。
(顺便说一句,我当然希望你至少使用SSL,而不是建议人们运行他们通过普通HTTP下载的代码而没有带外验证步骤。很多人都这样做,当然,但这是他们下载的网站 - 比如rvm.io
- 大目标。大,易于中间人或DNS劫持目标。)
答案 1 :(得分:1)
当你cat
打击要执行的代码时,来自标准输入的脚本。
read
从哪里读取?这也是标准输入。这就是为什么您可以cat
输入采用标准输入的程序(如sed
,awk
等)。
所以当你这样做时,你不会运行“脚本”。您正在运行一系列输入行。
您希望read
从哪个位置读取此设置中的数据?
您可以手动执行此操作(如果您可以定义此类位置)。或者,你可以像这样停止运行你的脚本。