
Ich habe ssh
zum Entpacken einer Remote-Datei Folgendes verwendet:
ssh host "cat file.tgz" | tar xf -
Das funktioniert einwandfrei. Allerdings ist mir beim Experimentieren mit erzwungenen Befehlen aufgefallen, dass die PTY-Zuweisung die Ausgabe des Befehls ändert:
ssh host -T "cat file.tgz" >first_file
ssh host -t "cat file.tgz" >second_file
Hier ist die erste Datei in Ordnung, aber die zweite Datei ist beschädigt.
Warum genau ändert die Zuweisung eines PTY die Ausgabe?
Antwort1
Es hilft, diessh
Handbuchseite:
-T Disable pseudo-tty allocation.
-t Force pseudo-tty allocation. This can be used to execute arbi‐
trary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
Wenn du es sagstZuteilenAPseudo-Tty, kann jeder Prozess auf der Remote-Seite erkennen, dass es sich bei der Verbindung um ein „echtes“ Terminal handelt, und wird zusätzliche Nachrichten senden, da die Verbindung interaktiv ist. Bei der Initialisierung Ihrer Shell können auch die Terminalmodi eingerichtet werden, die Sie mit überprüfen können stty -a
. Terminalmodi werden verwendet, umübersetzenzwischen Ihrer Tastatureingabe und dem Host und zwischen Text, der vom Host an Ihr Terminal gesendet wird:
- OhneInitialisierung, die Verbindung ist kein Terminal und es wird keine Übersetzung durchgeführt.
- MitBei der Initialisierung konvertiert das Terminal Newline (
\n
) in Wagenrücklauf und Zeilenvorschub (0x0d, 0x0a). Außerdem konvertiert es (für die meisten Benutzer) Tabulatoren in Leerzeichen.
Der beschriebene Effekt ist fürÜbersetzung. Ohne dasinteraktivDie Sitzung würde sich treppenartig über den Bildschirm erstrecken und unbrauchbar sein.
Ihre Shell kann auch zusätzliche Informationen ausgeben, aber für einen einzelnen Befehl ist dieAnregungvon @kba ist irreführend, da die Shell normalerweise keineEingabeaufforderungen, und die SSH-Kontrollen wie ~C
erwähnt gelten fürEingangstattAusgabe.
Beim Ausführen auf einem Terminal gibt ssh auch beim Schließen der Verbindung eine Meldung aus. Diese wird jedoch in die Standardfehlermeldung geschrieben.
Antwort2
Warum genau ändert die Zuweisung eines PTY die Ausgabe?
Weil die Remote-Seite (mit zugewiesenem Terminal) Steuerzeichen für Ihr lokales Terminal "einfügt" (grundsätzlich C0 und C1 Steuercodes). Und da Ihre lokale Seite kein Terminal, sondern eine Datei ist, werden sie einfach in diese Datei geschrieben.
SSH versucht, so gut wie möglich zu erraten, was Sie wollen (wenn stdin nicht TTY ist, wird kein Remote-TTY zugewiesen, es sei denn, Sie fügen -tt
Schalter hinzu). Die Option ist aus einem bestimmten Grund vorhanden und wenn Sie eine binäre Übertragung wünschen, möchten Sie nicht, dass Terminals Ihre Datei manipulieren.
Sie können dieses Verhalten sehen, indem Sie einfach kleine Dateien übertragen und dann einen Hexdump ausführen:
$ ssh -t host "cat test" > /tmp/test.t
$ ssh host "cat test" > /tmp/test
$ hexdump -C /tmp/test
00000000 0a 2a 20 46 72 69 20 46 65 62 20 31 32 20 32 30 |.* Fri Feb 12 20|
00000030 6d 3e 20 33 2e 34 2e 31 2d 31 0a 2d 20 4e 65 77 |m> 3.4.1-1.- New|
$ hexdump -C /tmp/test.t
00000000 0d 0a 2a 20 46 72 69 20 46 65 62 20 31 32 20 32 |..* Fri Feb 12 2|
00000030 6f 6d 3e 20 33 2e 34 2e 31 2d 31 0d 0a 2d 20 4e |om> 3.4.1-1..- N|
Für mich liegt der Unterschied nur in den zwei Bytes 0d 0a
vor jeder neuen Zeile, aber es können auch mehr sein (unter Linux besteht die Zeilenumbruchfunktion nur aus \n
, aber das Terminal erhält beide \r\n
).