Die Verwendung einer Dateieingabe als stdin für ein Shellskript funktioniert nicht

1126
Mohamed KALLEL

Ich habe den folgenden Skriptcode:

test.sh

echo "BEGIN" while read CMD <&1; do [ -z "$CMD" ] && continue case "$CMD" in start) echo "get_start" ;; stop) echo "get_stop" ;; *) echo "get_uknown_command" ;; esac echo "END"; done 

Wenn ich es mit:

$./test.sh <input.txt 

Ich bekomme mein Skript gesperrt

input.txt

start stop sthh 

Warum ist mein Skript gesperrt? Wie kann ich das beheben?

BTW: Wenn ich die Daten manuell eingebe, wird das Skript nicht gesperrt.

0

2 Antworten auf die Frage

3
John Szakmeister

Sie verwenden die falsche Dateibeschreibung. 1ist stdout, 0ist stdin.

Veränderung:

while read CMD <&1; do 

zu:

while read CMD <&0; do 

Und es wird aus der Datei richtig. Sie müssen dies jedoch nicht alles tun, da readstandardmäßig stdin verwendet wird:

while read CMD; do 

Außerdem kann die -uOption verwendet werden, um aus einem bestimmten Dateideskriptor zu lesen (zumindest in bash). So kannst du das auch tun:

while read -u 0 CMD; do 
2
a CVn

Dateideskriptor 1ist stdoutoder Standardausgabe . Was bedeutet, dass Sie die Eingabe so umleiten read, dass sie von der Standardausgabe stammt . Das wird offensichtlich nicht sehr gut funktionieren; es wird fast sicher nie eine Eingabe auf die Standardausgabe warten read.

Die Standardeingabe ist eine Dateideskriptor. 0Wenn Sie also <&1in <&0Zeile 2 Ihres Skripts wechseln, funktioniert es. Oder einfach diesen Teil ganz fallen lassen; readLiest standardmäßig von der Standardeingabe (das ist eigentlich nur der Zweck), so dass es nicht explizit angegeben werden muss, dass die Standardeingabe gelesen werden soll.

Wenn Sie bestimmte Eingaben interaktiv lesen möchten und zulassen möchten, dass der Rest aus einer Datei umgeleitet wird (oder durch eine Pipe kommt), können Sie dies tun read </dev/tty.

Nach dem END-Echo brauchen Sie das Trennzeichen für die Semikolon-Anweisung nicht. der Newline geht gut.