it-swarm.com.de

Shell-Skript stoppt beim Lesen der Zeilenschleife nach der ersten Zeile

Ich habe das folgende Shell-Skript. Der Zweck ist, durch jede Zeile der Zieldatei (deren Pfad der Eingabeparameter für das Skript ist) eine Schleife zu erstellen und gegen jede Zeile zu arbeiten. Jetzt scheint es nur mit der allerersten Zeile in der Zieldatei zu funktionieren und stoppt, nachdem diese Zeile verarbeitet wurde. Stimmt etwas mit meinem Skript nicht?

#!/bin/bash
# SCRIPT: do.sh
# PURPOSE: loop thru the targets 

FILENAME=$1
count=0

echo "proceed with $FILENAME"

while read LINE; do
   let count++
   echo "$count $LINE"
   sh ./do_work.sh $LINE
done < $FILENAME

echo "\ntotal $count targets"

Im do_work.sh, Ich führe ein paar ssh Befehle aus.

83
bcbishop

Das Problem ist, dass do_work.shssh Befehle ausführt und standardmäßig ssh von stdin liest, der Ihre Eingabedatei ist. Infolgedessen wird nur die erste Zeile verarbeitet, da ssh den Rest der Datei verbraucht und die while-Schleife beendet wird.

Um dies zu verhindern, übergeben Sie die Option -n An Ihren Befehl ssh, damit er von /dev/null Anstelle von stdin gelesen wird.

149
dogbane

die Option ssh -n verhindert, dass der Exit-Status von ssh überprüft wird, wenn HEREdoc verwendet wird, während die Ausgabe an ein anderes Programm weitergeleitet wird. Daher wird die Verwendung von/dev/null als Standard bevorzugt.

#!/bin/bash
while read ONELINE ; do
   ssh [email protected]_xyz </dev/null <<EOF 2>&1 | filter_pgm 
   echo "Hi, $ONELINE. You come here often?"
   process_response_pgm 
EOF
   if [ ${PIPESTATUS[0]} -ne 0 ] ; then
      echo "aborting loop"
      exit ${PIPESTATUS[0]}
   fi
done << input_list.txt
5
jacobm654321

Im Allgemeinen besteht eine für ssh nicht spezifische Problemumgehung darin, die Standardeingabe für jeden Befehl umzuleiten, der andernfalls die Eingabe der while -Schleife verbrauchen könnte.

while read -r LINE; do
   let count++
   echo "$count $LINE"
   sh ./do_work.sh "$LINE" </dev/null
done < "$FILENAME"

Das Hinzufügen von </dev/null Ist hier der entscheidende Punkt (obwohl das korrigierte Anführungszeichen auch etwas wichtig ist; siehe auch Wann muss eine Shell-Variable in Anführungszeichen gesetzt werden? ). Sie sollten read -r Verwenden, es sei denn, Sie benötigen speziell das etwas merkwürdige Verhalten, das Sie ohne -r Erhalten.

Eine andere Art von Problemumgehung, die etwas spezifisch für ssh ist, besteht darin, sicherzustellen, dass für jeden ssh -Befehl die Standardeingabe verknüpft ist, z. durch Austausch

ssh otherhost some commands here

um stattdessen die Befehle aus einem Here-Dokument zu lesen, das (für dieses spezielle Szenario) die Standardeingabe von ssh für die Befehle bequem verknüpft:

ssh otherhost <<'____HERE'
    some commands here
____HERE
2
tripleee