Wie leitet man die Ausgabe eines Befehls in eine Datei um, wenn der Befehl Benutzereingaben erfordert?

Wie leitet man die Ausgabe eines Befehls in eine Datei um, wenn der Befehl Benutzereingaben erfordert?

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.txtwird 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.txtDatei.

Wenn Sie es ausführen, /bin/bash Script2.sh > abc.txtwird die Frage „Geben Sie einen Kommentar ein“ angezeigt, Sie finden in der abc.txtDatei 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.txtDatei 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.txtund 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ützlicheteeDas

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 -pden 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.

Antwort2

Standardmäßig STDOUTwird nur umgeleitet und/oder weitergeleitet. Sie möchten es STDOUTso lassen und alles, was weitergeleitet wird, umleiten lassen STDIN.

Wenn Bearbeiten the_commandeine Option ist, können Sie sicherstellen, dass die Frage STDERRstattdessen 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 STDOUTeinschließ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?

verwandte Informationen