读取输入,同时通过stdin管道脚本

时间:2014-11-20 17:50:53

标签: bash shell

我有一个简单的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执行它一样?
  • 如何避免Bash逐行执行,但在STDIN到达结束后执行所有行?

2 个答案:

答案 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输入采用标准输入的程序(如sedawk等)。

所以当你这样做时,你不会运行“脚本”。您正在运行一系列输入行。

您希望read从哪个位置读取此设置中的数据?

您可以手动执行此操作(如果您可以定义此类位置)。或者,你可以像这样停止运行你的脚本。