
Ich habe einen Befehl, der den Benutzer zu einigen Eingaben auffordert und dann das Ergebnis an das Terminal ausgibt. Ich habe den Befehl wie folgt eingegeben, um die Ausgabe in eine Datei umzuleiten:
$the_command > abc.txt
Aber es funktioniert nicht. Das Problem ist, dass es keine Eingabeaufforderung gibt. Der Text dieser Eingabeaufforderungsfragen wird in abc.txt ausgegeben und liefert nicht das gewünschte Ergebnis.
Antwort1
Ihr Befehl funktioniert und leitet die Ausgabe ordnungsgemäß in die Datei um abc.txt
.
Die Frage istwie fragt Ihr Skript die Eingabedaten abund wie führen Sie das Skript aus?
Sehen wir uns das anhand von zwei Beispielen an:
# Script_1.sh # 1
echo Please, enter your firstname and lastname # 2
read FN LN # 3
echo "Hi! $LN, $FN !" # 4
Und
# Script_2.sh # 5
read -p "Enter a comment " CM # 6
echo "You said $CM" # 7
Wenn Sie es ausführen, /bin/bash Script1.sh > abc.txt
wird die Frage „Bitte geben Sie ein …“ auf Ihrem TTY nicht angezeigt. Wenn Sie die erwartete Eingabe über die Tastatur vornehmen, finden Sie die Ausgabe der Zeilen 2 und 4 in Ihrer abc.txt
Datei.
Wenn Sie es ausführen, /bin/bash Script2.sh > abc.txt
wird die Frage „Geben Sie einen Kommentar ein“ angezeigt, Sie finden in der abc.txt
Datei jedoch nur die Ausgabe der Zeile Nr. 7.
Hinweis: Wenn Sie Script2,sh in einer Subshell ausführen
(bash Script2.sh 2>&1)> abc.txt
Sie werden keine Ausgabe auf tty sehen und Sie werden alles in der abc.txt
Datei finden.
Wenn Sie es ausführen mit
bash Script2.sh 2>ccc.txt 1>ddd.txt`
Sie finden die Standardausgabe (Zeile Nr. 7) in ddd.txt
und den Standardfehler (Zeile Nr. 6) in ccc.txt
.
Falls Sie es wollenum nur einen Teil Ihrer Befehlsausgabe umzuleitenSie müssen Ihr Skript ändern.
Eine Möglichkeit besteht darin, eine Funktion zu erstellen, in die der Teil des Skripts verschoben wird, der die interessante Ausgabe erzeugt (siehe unten). Anschließend können Sie diese Funktion aus demHauptteilIhres Skripts (wo sich ursprünglich der Code befand, den Sie in die Funktion verschoben haben) und leiten Sie nur diese Ausgabe in die Protokolldatei um:
Part_To_Redirect(){
: # all that you want
}
# ... Main part of the script
# point where it was the part that generates the output
Part_to_Redirect "$@" > abc.txt # this to store only that part in the file
# Part_to_Redirect "$@" >> abc.txt # this to append that part in the file
# ...
Sie sollten sogar nützlichetee
Das
leitet die Ausgabe in mehrere Dateien um,kopiert die Standardeingabe in die Standardausgabeund auch auf alle als Argumente angegebenen Dateien.
the_command | tee abc.txt # To redirect Standard output
or
the_command 2>&1 | tee abc.txt # To redirect err in out and both in the file
In diesem Fall erhalten Sie die normalen Ausgaben Ihres Befehls auf dem TTY, speichern aber gleichzeitig eine Kopie in der Protokolldatei abc.txt
. In Ihrem Fall sollte es bequem sein, wenn Sie read -p
den Aufruf wie in Skript2 verwenden the_command | tee abc.txt
.
Hinweise und Referenzen:
Hinzufügen "$@"
können Siealle Argumente weitergebenIhres Skripts zur Funktion.
Möglicherweise ist es für Sie interessant, in den zahlreichen Quellen im Internet mehr über die Bash-Umleitung zu erfahren.
- Wie vorgeschlagen vonScottin seinem Kommentar gibt es eineWiki-Antwort von Unix SE: ein guter Ausgangspunkt.
- Ein Muss das
man bash
oderdas Bash-Handbuch. - Ich fand das Umleitungskapitel vonBash-HackerHier finden Sie Links zuveraltete Verwendungenzu.
- Weitere Informationen finden Sie imErweitertes Bash-Scripting-Handbuch, auch Kapitel 20.
Antwort2
Standardmäßig STDOUT
wird nur umgeleitet und/oder weitergeleitet. Sie möchten es STDOUT
so lassen und alles, was weitergeleitet wird, umleiten lassen STDIN
.
Wenn Bearbeiten the_command
eine Option ist, können Sie sicherstellen, dass die Frage STDERR
stattdessen an ausgegeben wird (das sollte sie ungeachtet eventueller Weiterleitungen auf dem Bildschirm ausgeben) und dann alles, was der Benutzer eingibt, über auf dem Bildschirm wiedergeben STDOUT
.
Antwort3
Normalerweise gibt es zwei wichtige Ausgabe-Pipes: STDOUT
(für die normale Ausgabe) und STDERR
(für Fehlermeldungen).
Das Problem hierbei ist, dass die „normale“ Ausgabe des Befehls und der Text der Eingabeaufforderung beide in geschrieben werden STDOUT
, also immer an derselben Stelle abgelegt werden. Wenn Sie Ihre Umleitung verwenden, wird nur die gesamte Ausgabe STDOUT
einschließlich der Eingabeaufforderung übernommen.
Wenn das Umschreiben des Befehls (wie in einer anderen Antwort von Jarmund vorgeschlagen) nicht möglich ist, verfügt der Befehl vielleicht über eine zusätzliche Option/Flagge (wie --output
), mit der anstelle der Umleitung eine Ausgabedatei angegeben werden kann?