fragen stichworte

Wie kann man verhindern, dass das Skript stdin vollständig verschluckt?

Ich habe ein Skript, das aus einer Pipe in einer Schleife liest und ein Expect-Skript und ein normales Shell-Skript in der Schleife ausführt. Beide Skripts führen ssh auf einem anderen Server aus, um ein Datenelement abzurufen. Zum Beispiel:

cat/tmp/file |
while read a b c d
do
   s=`expect-script server1 $b`
   c=`ssh $b normal-script`
   echo $s $c
done

Obwohl in/tmp/file viele Zeilen vorhanden sind, wird das Skript nach der Verarbeitung der ersten Zeile beendet. Ich vermute, dass das Expect-Skript alles von stdin verschluckt, so dass nach seiner Rückkehr nichts mehr zu lesen ist. Wie kann ich das vermeiden? Ich möchte nicht, dass die von mir angerufenen Skripte aus dem Standard-Skript des Hauptskripts gelesen werden.

antworten

cat/tmp/file |
while read a b c d
do
    {
        s=`expect-script server1 $b`
        c=`ssh $b normal-script`
        echo $s $c
    } </dev/null
done

Mit der { command... } -Syntax können Sie eine Umleitung oder eine Rohrleitung auf eine Befehlsfolge anwenden.

Ich bemerke auch, dass Sie in Ihrem Beispiel cat nicht benötigen. Sie könnten dies tun:

while read a b c d
do
    ...
done </tmp/file

Es ist tatsächlich ssh, das stdin schlürft. Fügen Sie einfach die Option -n hinzu:

   c=$( ssh -n $b normal-script )

Wenn Sie dies nicht möchten, können Sie Ihre Shell-Schleife while von einem anderen Dateideskriptor lesen lassen und stdin unberührt lassen:

while read -u3 a b c d
do
    s=$( expect-script server1 $b )
    c=$( ssh $b normal-script )
    echo $s $c
done 3</tmp/file

(vorausgesetzt, bash/ksh/zsh für die Option read -u)