Ist es sicher, einen anderen Befehl in STDIN einzugeben, während der vorherige Befehl in STDOUT schreibt?


21

Vielleicht wurde dies schon einmal beantwortet, ich würde einen Link zu einer anderen Antwort begrüßen ...

Wenn ich einen Shell-Befehl (in einer bashShell) wie folgt ausführe :

make

Dann , während der Ausgang makewird kontinuierlich durch von der STDOUTder makeBefehl, wenn ich schreibe , make checkund drücken , enterbevor der erste Befehl beendet ausgeführt wird , wenn der makeBefehl schließlich endet der nächste Befehl make checkrechts und laufen abholt.

Meine Frage (n) sind einfach:

  1. Ist das gefährlich zu tun?
  2. Gibt es irgendwelche potenziellen unerwarteten Verhaltensweisen aufgrund dieser Art von Eiltippen?
  3. Warum funktioniert das so?

2
1. Ich hoffe es ist nicht ... Ich mache das schon seit Jahren!
John WH Smith

Antworten:


20

Es funktioniert so, wie es funktioniert, weil Unix Vollduplex ist. Wie Ritchie im UNIX-Timesharing-System sagte : Ein Rückblick :

Eine Sache, die trivial erscheint, aber einen überraschenden Unterschied macht, wenn man sich erst einmal daran gewöhnt hat, ist die Vollduplex-Terminal-E / A zusammen mit dem Vorauslesen. Obwohl Programme mit dem Benutzer im Allgemeinen in Form von Zeilen und nicht in Form von einzelnen Zeichen kommunizieren, bedeutet die Vollduplex-Terminal-E / A, dass der Benutzer jederzeit tippen kann, auch wenn das System zurücktippt, ohne befürchtet, Zeichen zu verlieren oder zu verstümmeln . Beim Vorauslesen muss nicht auf jede Zeile eine Antwort gewartet werden. Ein guter Schreiber, der ein Dokument eingibt, ist unglaublich frustriert darüber, dass er vor jeder neuen Zeile eine Pause einlegen muss. für jeden, der weiß, was er sagen will, wird eine Langsamkeit der Antwort psychologisch vergrößert, wenn die Informationen Stück für Stück eingegeben werden müssen, anstatt mit voller Geschwindigkeit.

[Zitat beenden]

Davon abgesehen gibt es einige moderne Programme, die jeden Tippfehler auffressen oder verwerfen. sshund apt-getsind zwei Beispiele. Wenn Sie während der Ausführung einen Tippvorgang ausführen, ist möglicherweise der erste Teil Ihrer Eingabe verschwunden. Das könnte möglicherweise ein Problem sein.

ssh remotehost do something that takes 20 seconds
mail bob
Dan has retired. Feel free to save any important files and then do
# ssh exits here, discarding the previous 2 lines
rm -fr *
.

Ist der erste Befehl nach bash fork()s und execs STDINder Bash-Shell noch zugeordnet? Es hört sich so an, als wäre die Antwort nein. Bash scheint für den nächsten Befehl zu puffern. Ist das korrekt?
111 ---

Wenn Sie die Shell nicht anweisen, die Standardeingabe des Befehls umzuleiten, hat der Befehl dieselbe Standardeingabe wie die Shell. Alles, was Sie eingeben, wird vom ersten Prozess gelesen, der es liest. Die Shell versucht absichtlich nichts zu lesen, während ein Befehl ausgeführt wird, und wartet, bis der Befehl beendet wird. Komplexer wird es, wenn Sie den Befehl mit in den Hintergrund stellen &.
Mark Plotnick

Also wird STDINfifo gehandhabt? Und ich nehme an, dass, wenn der untergeordnete Prozess von Bash sein geerbtes Datei-Handle nicht explizit schließt, STDINer dennoch aus der zusätzlichen Eingabe lesen könnte ?
111 ---

Ja, alle Terminal-Eingaben werden mit FIFO behandelt. Ich bin mir nicht sicher, ob ich deine zweite Frage verstehe. Der untergeordnete Prozess - der von der Shell aufgerufene Befehl - schließt die Standardeingabe normalerweise nicht explizit. Die Shell tritt aus dem Weg und lässt den Befehl alles lesen, was sie will. Dann stoppt das Kind und die Shell nimmt den Lesevorgang wieder auf.
Mark Plotnick

Ja, Sie haben meine beiden Anschlussfragen sehr deutlich beantwortet, danke!
111 -

12

Das grundlegende Verhalten Sie sehen , ist , dass die Eingabe in einem Puffer irgendwo sitzt , bis es gelesen hat (gut, wenn Sie genug geben, schließlich die Puffer füllt sich, und etwas verloren geht, dass ein sein würde viel Tipparbeit obwohl). Die meisten Dinge, die von make ausgeführt werden, lesen nicht aus STDIN, daher bleibt es im Puffer.

Die Gefahr besteht darin, dass der falsche Befehl Ihre Eingabe liest. Ruft beispielsweise makeetwas auf, das Sie dazu auffordert, und liest dann möglicherweise Ihren nächsten Befehl als Antwort. Wie gefährlich das ist, hängt natürlich vom Kommando ab. (Möglicherweise werden auch alle Eingaben zuerst gelöscht und nur Ihre vorherigen Eingaben verworfen.)

Ein Befehl, der häufig in Makefiles verwendet wird, ist TeX. Wenn ein Fehler auftritt (und dem Benutzer kein Flag zugewiesen wurde, um ihn nie zur Eingabe aufzufordern), werden Sie gefragt, wie Sie fortfahren möchten.

Eine bessere Option ist wahrscheinlich zu laufen: make && make check.


8
  1. Natürlich sollten Sie keinen zweiten Befehl ausführen, der davon abhängt, ob der erste Befehl ( makein Ihrem Beispiel) erfolgreich ausgeführt wurde. Könnte zum Beispiel make foo Enter> ./foo Enter ein Problem verursachen. Vielleicht möchten Sie versuchen, sich daran zu gewöhnen, Dinge wie zu schreiben make && make check, bei denen der zweite Befehl nur ausgeführt wird, wenn der erste erfolgreich ist.
  2. Es ist theoretisch möglich, dass der erste Befehl (Prozesse) einen Teil des zweiten Befehls liest oder ihn auf andere Weise aus dem Terminal-Eingabepuffer entfernt. Wenn es die ersten sechs Zeichen von aß make check, würden Sie am Ende den Befehl ausführen heck, der auf Ihrem System wahrscheinlich nicht vorhanden ist (aber möglicherweise etwas unangenehmes ist). Wenn der erste Befehl etwas Gutes ist, das Sie kennen und dem Sie vertrauen, sehe ich kein sofortiges Problem.
  3. Wie / warum funktioniert das? Das System puffert Tastatureingaben. Es ist ein bisschen wie bei einer E-Mail: Sie können einer Person in kurzer Zeit fünf Nachrichten senden, und sie sitzt in ihrem Posteingang und wartet darauf, dass er sie liest. Solange der erste Befehl nicht von der Tastatur liest, warten die von Ihnen eingegebenen Befehle darauf, dass die Shell sie liest. Es gibt eine Begrenzung, wie viel Vorausschreiben gepuffert werden kann, aber gewöhnlich sind es mehrere Hundert Zeichen (wenn nicht mehrere Tausend).

2
Stellen Sie sich zu Punkt 1 vor, dass die Befehle unabhängig sind, dh lsund mountzum Beispiel. Ich versuche zu verstehen, wie die gepufferte Eingabe behandelt wird. Danke für die Antwort.
111 ---
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.