2つのスクリプトがあります。
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
。これら2つのスクリプトが同じであることを願っています。
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
stdinでデータを食べないようにするには、を使用します。これにより、ループのstdinではなくwithのstdinがssh -n
リンクされます。ssh
/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