
Ich schreibe SML-Programme und hätte gern eine Möglichkeit, schnell die Ausgabe eines ausgeführten Programms im REPL anzuzeigen, ohne das REPL tatsächlich auszuführen (um schnell zu sehen, ob ein Programm Syntaxfehler enthält. Ich plane, dies als Make-Programm für SML-Dateien in Vim zu verwenden, um die Ausgabe in Vim anzuzeigen). Derzeit habe ich Folgendes:
sml file.sml | echo -e "\004"
Es führt also das Programm aus und gibt dann Strg-D aus, um das REPL zu beenden. Das Problem ist, dass es die Strg-D-Taste zu schnell sendet, sodass keine Ausgabe erfolgt. Ich habe auch Folgendes versucht:
sml file.sml | sleep 2 ; echo -e "\004"
Aber das funktioniert auch nicht. Irgendwelche Ideen, wie ich einen Dump der Ausgabe vom REPL erhalten kann?
Antwort1
Nein, das Problem besteht darin, dass Sie die Funktionsweise von Rohren falsch verstehen.
In Unix-Pipelines fließen Datenvon links nach rechts(dieselbe Richtung wie geschriebener Text im Englischen) – die Ausgabe des ersten Programms wird zur Eingabe des zweiten Programms. Die Pipes sind jedoch unidirektional; die Ausgabe des zweiten Programms wird nicht an das erste Programm gesendet.
Wenn du läufst sml file.sml | echo -e "\004"
,sind nichtCtrl+D wird wiederholt sml
. Stattdessen werden SieWeiterleitung sml
der Ausgabe an den echo
Befehl– wo es verworfen wird, da echo
stdin nicht verwendet wird.
- Tastatur →
sml file.sml
→echo -e "\004"
→ Bildschirm
Ihr zweiter Versuch, sml file.sml | sleep 2 ; echo -e "\004"
, hat ein ähnliches Problem – die Ausgabe von sml
wird an gesendet sleep
(wobei auch die empfangene Eingabe verworfen wird). Es gibt jedoch ein weiteres Problem: Der echo
Befehl ist jetzt überhaupt nicht Teil der Pipeline; man könnte sagen, dass |
hat eine höhere Priorität als ;
. (Sie könnenGruppieren Sie Befehle mit Klammern; z.B a | (b; c; d)
.)
- Tastatur →
sml file.sml
→sleep 2
→ Bildschirm - Tastatur →
echo -e "\004"
→ Bildschirm
Wie bereits oben erwähnt, sind beide Versuche in derfalsche Richtung\004
Wenn Sie das Zeichen an senden wollten sml
, hätte die Pipeline folgendermaßen geschrieben werden müssen:
echo -e "\004" | sml file.sml
wobei sml
die Ausgabe von wie vorgesehen auf dem Bildschirm angezeigt wird.
Es gibtein weiteres Problem, aber. Sie sind auchVerwechseln des CtrlDTastendrucks mit dem „Ende der Eingabe“Ereignis.
Die Übersetzung von CtrlDin „Ende der Eingabe“ erfolgt nur auf der Ebene des Terminalgeräts – also nur, wenn Sie das Zeichen Strg+D in Ihr Terminalfenster eingeben. Wenn Sie es jedoch echo -e "\004"
in einer Pipe verwenden, ist esnichtautomatisch in „Ende der Eingabe“ übersetzt; stattdessen wird das tatsächliche Byte 004 [Oktal] geschrieben.
Wenn Sie dem Programm tatsächlich mitteilen möchten, dass keine Eingabe mehr erfolgt, dannschreib nichts. Verwenden Sie einen Befehl, der nichts ausgibt – beispielsweise echo -n
oder true
, oder leiten Sie die Eingabe einfach aus der /dev/null
Datei um.
echo -n | sml file.sml
sml file.sml < /dev/null