我有两个脚本:
foo.sh:
#!/bin/bash
echo -e "one\ntwo" |
while read line; do
cat not-existing
echo hello $line
done
酒吧.sh:
#!/bin/bash
echo -e "one\ntwo" |
while read line; do
ssh user@machine 'cat not-existing' # Here is the only difference
echo hello $line
done
现在我运行它们
$ ./foo.sh
cat: not-existing: No such file or directory
hello one
cat: not-existing: No such file or directory
hello two
$ ./bar.sh
cat: not-existing: No such file or directory
hello one
的输出bar.sh
令我惊讶。我希望这两个脚本是相同的。
foo.sh
为什么和的输出bar.sh
不同?这是一个错误还是一个功能?
笔记
以下内容按我的预期工作,即其输出与 的输出相同foo.sh
:
#!/bin/bash
for line in `echo -e "one\ntwo"`; do
ssh user@machine 'cat not-existing'
echo hello $line
done
为什么?
答案1
在 中bar.sh
,two
被 消耗ssh
。在最后一个示例中,在开始循环之前echo
使用了from 的完整输出。for
为了避免ssh
从标准输入中吞噬数据,请使用ssh -n
.这将连接ssh
with的标准输入/dev/null
,而不是while
循环的标准输入。
这将执行您期望的操作:
#!/bin/bash
echo -e "one\ntwo" |
while read line; do
ssh -n user@machine 'cat not-existing' # Here is the only difference
echo hello $line
done
如果你写过
#!/bin/bash
echo -e "one\ntwo" |
while read line; do
ssh user@machine 'cat'
echo hello $line
done
那么cat
远程机器上的 就会输出,two
因为它的标准输入被传递给它,ssh
而 又从循环中得到它echo
。它将打印two
而不是one
因为第一行输入已被 消耗read
。