Christian Weisgerber <
na...@mips.inka.de>:
>On 2022-08-17, Helmut Waitzmann <
nn.th...@xoxy.net> wrote:
>
>> ssh -t -- account@rechner &
>>
>> Der Job läuft los und stoppt. Ich kann ihn mit dem Kommando «fg»
>> in den Vordergrund holen und dann beispielsweise ein Kommando,
>> etwa
>>
>> stty
>>
>> blind eintippen, das heißt, ich sehe nicht, was ich tippe. Wenn
>> ich das Kommando abschicke, erhalte ich die Ausgabe
>
>Ja, ich kann das jetzt reproduzieren. Dazu braucht man die passende
>Login-Shell wie bash. Mit tcsh dagegen tritt der Effekt gar nicht
>auf, pdksh verdeckt das Problem.
>
>Ich werde mir das mal genauer anschauen.
>
>
>> speed 38400 baud; line = 0;
>> lnext = <undef>; discard = <undef>; min = 1; time 0;
>> -brkint -icrnl -imaxbel iutf8
>> -icanon -echo
>>
>> und den nächsten Prompt vom Shell auf «rechner». «-echo» in der
>> Ausgabe von «stty» auf dem entfernten Rechner erklärt das
>> Verhalten.
>
>Nur zufällig.
>
Nicht ganz zufällig (sondern mit Absicht, aber nicht ursächlich).
Es ist richtig, was du im folgenden beschreibst:
>Praktisch alle Shells im interaktiven Betrieb
>(1) sichern die TTY-Einstellungen,
>(2) setzen eigene Einstellungen, während sie am Prompt Eingaben
> entgegennehmen,
>(3) schalten vor der Befehlsausführung auf die gesichterten
> Einstellungen zurück,
>(4) nachdem der Befehl beendet ist, gehe zu (1).
>
>Das heißt, dass dir stty die Einstellungen bei der
>Befehlsausführung zeigt, aber _nicht_ die am Shellprompt.
Ja, das ist richtig. Aber Shells tun gut daran, bei der Abarbeitung
von (2) und anschließender Verwendung des Terminals bei der
Entgegennahme von Eingaben am Prompt sich an (1) zu orientieren:
Beispielsweise sollten sie gerade die Echo‐Einstellungen von (1)
beachten: Finden sie das Echo der kanonischen Terminal‐Betriebsart
abgeschaltet vor, sollten sie auch in ihrer Emulation (2) kein Echo
simulieren, weil sie davon ausgehen sollten, dass der Anwender
tatsächlich kein Echo haben will (beispielsweise, damit niemand, der
ihm über die Schulter schaut, sieht, was er gerade (an
Shell‐Kommandos) eintippt).
>Um letztere zu sehen, muss man von einem separaten Login mit stty
>jenes TTY abfragen, wo die Shell gerade mit dem Prompt wartet. Und
>das beobachtete Problem war ja das fehlende Echo am Prompt.
Ja. Der jeweilige Aufruf von «stty» auf dem entfernten Rechner gibt
nur einen Hinweis, dass der Shell in beiden Fällen verschiedener
Meinung darüber ist, welche Echo‐Einstellungen das Terminal haben
sollte, solang vom Shell gestartete Programme (hier: «stty») laufen.
Bleibt also die Frage, warum der Shell auf dem entfernten Rechner
der Meinung ist, unterschiedliche Terminal‐Einstellungen vornehmen
zu müssen, wenn es Programme (hier: «stty» startet), und sich
unterschiedlich verhalten zu sollen, jeweils abhängig davon, ob
«ssh» im Vordergrund oder im Hintergrund gestartet wurde: Wurde
«ssh» im Vordergrund gestartet, entscheidet es sich dafür, mit
eingeschaltetem Echo zu arbeiten bzw. eingetippte Zeichen zu
spiegeln, wurde es hingegen im Hintergrund gestartet, entscheidet es
sich dafür, es bleiben zu lassen.
Die Antwort würde ich in der folgenden Richtung suchen: Was
erhalten Programme, die im Hintergrund laufen, an Information vom
Terminal, wenn sie – wie «stty» – nach Terminal‐Einstellungen
fragen?
Dazu starte ich jetzt einfach mal ohne «ssh» lokal aus einem «bash»
heraus:
stty -a &
Das liefert mir auf Debian 10 unter anderem «-echo» (also kein
Echo), während
stty -a
«echo» (also mit Echo) liefert.
Wiederhole ich den Versuch aus einem «dash» heraus, erhalte ich in
beiden Fällen «echo»!
Da scheint also der Hase im Pfeffer zu liegen: «bash» startet
Kommandos im Hintergrund mit abgeschaltetem Echo auch dann, wenn das
Echo an sich (als) eingeschaltet (zu betrachten) ist.
Bis jetzt (also, ohne weitere Gründe zu kennen oder Folgen
abzuschätzen) betrachte ich das als Fehler: Ich meine bisher, das
Kommando
ein Kommando
sollte mit dem Kommando
{ ein Kommando & } ; fg
so äquivalent wie irgend möglich sein.
Die Gegenprobe, aus einem «dash» heraus «ssh» im Hintergrund zu
starten und das dann gestoppte «ssh» nachträglich in den Vordergrund
zu holen, liefert in der Tat ebenfalls eingeschaltetes Echo beim
Start des Kommandos «stty -a» auf dem entfernten Rechner und der
«bash» auf dem entfernten Rechner spiegelt die eingetippten Zeichen
zurück.
>Die tatsächlichen TTY-Einstellungen am Prompt sind hier aber auch
>nicht sehr hilfreich, weil z.B. bash grundsätzlich echo abschaltet
>und Zeichen selbst ausgibt. Dass "stty -echo" dann bash überhaupt
>beeinflusst, liegt offenkundig daran, dass bash diese Einstellung
>auswertet und das eigene Verhalten anpasst;
Und das halte ich auch für richtig so: Schließlich soll «bash» ja
die nach Beendigung von «stty -echo» vorgefundene kanonische
zeilenweise Terminal‐Betriebsart möglichst originalgetreu
simulieren. (Die Simulation ist ja unter anderem deshalb notwendig,
weil «bash» wegen des command line editors und wegen auto‐completion
an die Kommandozeile bereits rankommen muss, ehe sie fertig
eingetippt und abgeschickt worden ist.) Und dazu gehört auch, den
Echo‐Zustand des Terminals nach dem Ende von «stty» zu respektieren.
Jetzt habe ich einen so schönen Beitrag geschrieben und nochmals
Versuche gemacht, und siehe da: Es wird noch verzwickter! War
alles für die Katz'?
Wenn ich in einem «bash» das Kommando
stty -a &
laufen lasse und diesen Versuch mehrmals wiederhole, erhalte ich
manchmal u. a. «-echo» und manchmal «echo»! Da scheint also irgend
ein race condition zwischen der Terminal‐Umstellung, die «bash»
vornimmt und dem gleichzeitigen Lauf von «stty» stattzufinden. Rufe
ich statt dessen
( sleep -- 1; stty -a ) &
auf, habe ich bei allen bisherigen Versuchen «-echo» erhalten. Und
das passt ja auch dazu, dass «bash» für seine Emulation der
kanonischen Terminal‐Betriebsart das Echo ausschaltet, weil es sein
Tasten‐Echo selber machen will (und muss). Also könnte man meinen,
dass in der Kommandozeile
( sleep -- 1; ein_Kommando ) &
«ein_Kommando» immer mit ausgeschaltetem Tasten‐Echo läuft
(vorausgesetzt, die Sekunde Wartezeit reicht dem «bash», das
Terminal wieder für sich passend einzustellen). Also starte ich
jetzt mal
( sleep -- 1; stty -a ; bash ) &
Und natürlich sehe ich nach einer Sekunde wieder «-echo», und der
Job wird gestoppt. Hole ich ihn in den Vordergrund, erhalte ich den
neu gestarteten interaktiven «bash». Aber o Wunder! Er simuliert
ein Tastenecho, und auch ein darin gestartes
stty -a
liefert «echo»! Vermutung: Der äußere «bash» stellt beim
«fg»‐Kommando zuerst das Tastenecho wieder an, und der in den
Vordergrund geholte «bash» holt sich wieder die
Terminal‐Einstellungen aufs Neue und arbeitet deswegen jetzt mit
eingeschaltetem (bzw. simulierten) Tastenecho.
Und jetzt vermute ich den Unterschied zum ursprünglichen
«ssh»‐Aufruf im Hintergrund: Wenn «ssh» vom gestoppten Zustand in
den Vordergrund gebracht wird, bekommt der von ihm auf dem
entfernten Rechner gestartete «bash» davon nichts mit (vermutlich
wird der nicht einmal gemerkt haben, dass das lokale «ssh»‐Kommando
im Hintergrund und gestoppt gewesen ist). Deswegen hat er auch
keinen Grund, nach den Terminal‐Einstellungen zu sehen und das
Tastenecho zu simulieren.
Ob der Zustand des lokalen Terminals von «ssh» überhaupt an das vom
«sshd» auf dem entfernten Rechner betriebene Pseudo‐Terminal
übermittelt wird, weiß ich nicht sicher, vermute es aber.
Schließlich soll das entfernte Pseudo‐Terminal ja möglichst so wie
das lokale wirken. In dem Zusammenhang muss man auch bedenken, dass
«ssh», ähnlich wie ein interaktiver Shell, sein Terminal sicher
nicht in der kanonischen Betriebsart (also zeilenweise) betreibt.
Sonst könnte es ja auf ein Tildezeichen erst reagieren, wenn eine
ganze Zeile abgeschickt wird, und nicht sofort.
Andreas, da hast du ja ein interessantes Thema ans Licht gebracht!