(1 risposta)
Chiuso 4 anni fa.
Ho due script:
foo.sh:
#!/bin/bash
echo -e "onentwo" |
while read line; do
cat not-existing
echo hello $line
done
bar.sh:
#!/bin/bash
echo -e "onentwo" |
while read line; do
ssh [email protected] 'cat not-existing' # Here is the only difference
echo hello $line
done
E ora li eseguo
$ ./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
L'output di bar.sh
è sorprendente per me. Mi aspetto che sia lo stesso per entrambi gli script.
Perché l'output di foo.sh
e bar.sh
differire? È un bug o una funzionalità?
Nota
Quanto segue funziona come mi aspetto, ovvero l'output di questo è lo stesso dell'output di foo.sh
:
#!/bin/bash
for line in `echo -e "onentwo"`; do
ssh [email protected] 'cat not-existing'
echo hello $line
done
Perché?
Risposta accettata:
In bar.sh
, i two
viene consumato da ssh
. Nell'ultimo esempio, l'output completo da echo
è usato da for
prima che inizi il ciclo.
Per evitare di avere ssh
divorare i dati dall'input standard, utilizzare ssh -n
. Questo collegherà l'input standard di ssh
con /dev/null
piuttosto che con l'input standard del while
ciclo.
Questo farà quello che ti aspetti che faccia:
#!/bin/bash
echo -e "onentwo" |
while read line; do
ssh -n [email protected] 'cat not-existing' # Here is the only difference
echo hello $line
done
Se avessi scritto
#!/bin/bash
echo -e "onentwo" |
while read line; do
ssh [email protected] 'cat'
echo hello $line
done
poi il cat
sulla macchina remota avrebbe prodotto two
poiché il suo input standard gli viene trasmesso da ssh
che a sua volta lo ha ottenuto dal loop e da echo
. Stamperà two
anziché one
poiché la prima riga di input è già stata consumata da read
.