Ich habe ein Problem in einem meiner Shell-Skripte. Gefragt ein paar Kollegen, aber sie alle schütteln nur den Kopf (nach einigem Kratzen), also bin ich hierher gekommen, um eine Antwort zu bekommen.
Nach meinem Verständnis sollte das folgende Shell-Skript "Count is 5" als letzte Zeile ausgeben. Außer es tut nicht. Es wird "Count is 0" ausgegeben. Wenn das "while read" durch eine andere Art von Schleife ersetzt wird, funktioniert es einwandfrei. Hier ist das Skript:
Echo "1"> input.data Echo "2" >> input.data Echo "3" >> input.data Echo "4" >> input.data Echo "5" >> input.data CNT = 0 cat input.data | beim Lesen; machen let CNT ++; echo "Zählen bis $ CNT" getan echo "Count is $ CNT"
Warum passiert das und wie kann ich es verhindern? Ich habe dies in Debian Lenny und Squeeze ausprobiert, das gleiche Ergebnis (dh Bash 3.2.39 und Bash 4.1.5. Ich gebe voll zu, kein Shellskript-Assistent zu sein, daher wären alle Hinweise willkommen.
Dies ist eine Art "häufiger" Fehler. Pipes erstellen SubShells, so dass das
while read
auf einer anderen Shell als Ihrem Skript ausgeführt wird, sodass sich IhreCNT
Variable niemals ändert (nur die in der Pipe-Subshell).echo
Gruppierenwhile
Sie die letzte mit der Unterschale , um sie zu reparieren (es gibt viele andere Möglichkeiten, um sie zu reparieren, dies ist eine. Iain und Ignacios Antworten haben andere.)Lange Erklärung:
CNT
in Ihrem Skript den Wert 0;|
to gestartetwhile read
;$CNT
Variable wird mit dem Wert 0 in die SubShell exportiert.CNT
Wert auf 5.echo
Ihren ursprünglichenCNT
Wert von 0.quelle
Das funktioniert
quelle
let CNT++
die stattdessen verwendet werden sollteCNT="$((CNT+1))"
, um eine POSIX-konforme arithmetische Erweiterung zu verwenden . Der Rest ist bereits portabel.Versuchen Sie stattdessen, die Daten in einer Sub-Shell zu übergeben, wie es eine Datei vor der while-Schleife ist. Dies ähnelt der Lösung von lain, setzt jedoch voraus, dass Sie keine intermittierenden Dateien benötigen:
quelle