Warum wird die Beförderung von Beförderungen in Umleitungen schlecht behandelt?

474
Synxis

Lass uns den folgenden Code haben (hier in Python):

print("something\r any") 

Wenn Sie es in einer Konsole ausführen, wird Folgendes korrekt erzeugt:

 anything 

(Nach dem Drucken somethingkehrt der Einfügemarke an den Anfang der gleichen Zeile zurück und überschreibt dann die ersten vier Zeichen mit any).

Derselbe Befehl in einer Umleitung erzeugt jedoch:

something any 

was falsch ist. Wieso ist es so ? Gibt es etwas, das der Shell mitteilt, die aktuelle Zeile beim Umleiten neu zu schreiben?

Über die Definition von CR und LF:

Ein Zeilenvorschub bedeutet, eine Zeile vorwärts zu bewegen. Der Code ist \ n. Ein Wagenrücklauf bedeutet, den Cursor an den Zeilenanfang zu bewegen. Der Code lautet \ r.

2

2 Antworten auf die Frage

3
Maximus

Wenn Sie die Ausgabe umleiten, werden die Bytes unverarbeitet an das Ziel geschrieben. Wie stellen Sie sich beispielsweise vor, dass ANSI-Sequenzen zur Farbmanipulation bei der Umleitung "verarbeitet" werden? Gleiches mit CR. Es wird nur zur Ausgabe geschrieben.

Applications may detect that they are not connected to real tty device and choose different mode, "processing" codes internally. Perhaps, ncurses applications do that, but that's a courtesy I believe.

On the other hand, when you cat or type that captured file, raw codes would be processed by the tty device.

Nun, ich denke, es kann durchaus akzeptabel sein, dass die Verarbeitung in einer Umleitung erfolgt, indem beispielsweise Farbcodes einfach gelöscht werden (und CR korrekt behandelt wird). Synxis vor 8 Jahren 0
Nun, wie stellen Sie sich das vor, wenn Sie die Ausgabe an ein Gerät umleiten, das nur sequentiellen Zugriff bietet (schreiben Sie in unserem Fall)? Beispiel sind Schreibmaschinen oder CD-R, DVD-R-Brenner. Die Anwendung weiß nicht, was noch kommen würde, sie kann nicht vorhersagen, wann CR ohne LF erscheinen würde. Sie erwarten also in jeder Anwendung, die Sie jemals ausführen können, die Möglichkeit, die Ausgabe zwischenzuspeichern? Was ist mit Zeilen, die Kilo- und Megabytes enthalten, die sich hervorragend für XML / Json / Scripts eignen? Dies wäre nur bei bestimmten Anwendungen ohne Gewähr möglich ... p Maximus vor 8 Jahren 0
Die Shell könnte die letzte nicht abgeschlossene Zeile für einen solchen Fall unabhängig puffern, aber Sie haben einen Punkt mit riesigen xml / json-Zeilen. Vielleicht sollte es eine Option dafür geben ... Synxis vor 8 Jahren 0
-1
BillThor

Der Wagenrücklauf soll den Cursor an den linken Rand zurückbringen. Dies ist die Grundfunktionalität. Der Zeilenvorschub soll den Cursor um eine Zeile nach unten bewegen. Einige Software / Hardware wird nur die Grundfunktionen übernehmen. Andere Software / Hardware, die einen bloßen Wagenrücklauf und / oder einen bloßen Zeilenvorschub als Wagenrücklauf / Zeilenvorschubpaar behandelt. Was Sie sehen, sind Variationen dieses Verhaltens.

Verschiedene Betriebssysteme und andere Software verwenden entweder einen leeren Wagenrücklauf oder einen leeren Zeilenvorschub als Leitungsabschluss. Normalerweise rendern sie den Zeilenabschluss, indem sie an den Anfang der nächsten Zeile vorrücken. Das Verhalten erfordert, dass die Konsole einen Wagenrücklauf einfügt, wenn ein Zeilenvorschub gesendet wird. Versuchen Sie, Ihr Programm auszuführen, nachdem Sie dieses Verhalten mit dem Befehl deaktiviert haben stty -onlcr. Dies kann mit dem Befehl stty onlcroder rückgängig gemacht werden stty sane.

Die Ausgabe der Druckanweisung ist nicht verarbeitet und liefert die korrekte Ausgabe auf der Konsole. Wenn Sie ein anderes Terminal verwendet haben, erhalten Sie möglicherweise dieselben Ergebnisse wie beim Verarbeiten während der Pipeline.