Beenden der Ausgabe eines Programms, das JETZT in einer SSH-Sitzung ausgeführt wird


18

Problem

Ich führe einen Befehl aus, der VIELE Informationen über SSH ausgibt. Zum Beispiel füge ich törichterweise Debug-Informationen in eine Schleife ein, die millionenfach ausgeführt wird, oder laufe einfach nur cat /dev/urandomum die Wette.

Das Terminal ist mit Informationen überflutet.

Beispiel wovon ich rede

Ich möchte den Befehl so schnell wie möglich beenden und mein Programm reparieren. Es ist mir egal, was es druckt. Jetzt drücke ich Ctrl+ CSO BALD WIE MÖGLICH (im obigen Beispiel habe ich es sofort nach Ausführung des Befehls gedrückt), aber es dauert noch einige Zeit, bis alle Informationen gedruckt sind, die ich nicht einmal benötige .

Was ich versucht habe

Ich habe versucht, Ctrl+ Cso fest zu drücken , dass es komische Ergebnisse brachte, als das Terminal endlich aufholte:

OUTPUT HERE^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
^C^C

^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C

Ich habe auch über Ctrl+ gelesen, Sdas anscheinend verwendet wird, um dem Terminal mitzuteilen, dass "Ausgabe stoppen, ich muss aufholen", aber anscheinend tut es nichts.

Verschiedene Details

Ich möchte den Befehl, den ich ausführe, nicht ändern, damit ich mich in jeder Situation retten kann, auch wenn ich mich nicht erinnere, dass das von mir ausgeführte Programm so enden könnte.

Mein SSH-Client wird unter Cygwin ( CYGWIN_NT-6.1-WOW64 luna 1.7.30(0.272/5/3) 2014-05-23 10:36 i686 Cygwin) in MinTTY mit dem Terminaltyp "" ausgeführt xterm-256color.

SSH-Server läuft unter Debian ( Linux burza 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686 i686 i686 GNU/Linux).


Auf welchem ​​System führen Sie die eigentlichen Programme aus, die die Ausgabe erzeugen? Linux, Unix oder Windows? Linux und UNIX sollten akzeptieren Ctrl-O, was bedeutet, dass alle auf dieses Terminal geschriebenen Ausgaben verworfen werden.
Mark Plotnick

Der Server läuft unter Debian. Hat die Frage bearbeitet. Ctrl-O scheint auch nichts zu tun. Vielleicht ist es die Sache des Kunden?
rr

Sie können versuchen, Ihr xterm mit der -jOption zu starten , um das Jump-Scrolling zu aktivieren. Das Grundproblem besteht darin, dass die Fernbedienung Daten schneller senden kann, als das Terminalfenster dies anzeigen kann. Standardmäßig muss der Inhalt des Fensters bei jedem Ausdruck einer neuen Zeile bitweise angezeigt werden. Eine ganze Menge von Daten kann gepuffert werden, bis Ihr Ctrl-C vom Remote-System empfangen wird, und Ihr Terminal-Programm wird versuchen, alles anzuzeigen.
Mark Plotnick

Nur eine Idee: Wenn Sie einige exakte Befehle haben, die Sie normalerweise versehentlich ausführen und die eine Menge Ausgabe generieren, warum nicht einfach einige Aliase anhängen .bashrc?
Psimon

Sie könnten mosh anstelle von ssh verwenden: mosh.mit.edu
gmatht

Antworten:


5

Ein Teil dieser Ausgabe wird gepuffert. Sie senden Ihr Ctrl+ Can das entfernte Ende, wodurch das laufende Programm unterbrochen wird. Das Programm ist vorhanden und die Shell sendet die Zeichen, um Ihnen die Eingabeaufforderung erneut anzuzeigen. Bevor die Eingabeaufforderung angezeigt wird, zeigt Ihr Bildschirm zunächst alle Daten an, die gepuffert wurden und bereits auf dem Weg zu Ihnen sind.

Was Sie verlangen, ist, dass das Programm stoppt und die Daten, die gerade übertragen werden, irgendwie verschwinden. Das kann nicht passieren, da es bereits unterwegs ist.

Die einzige Möglichkeit, sicherzustellen, dass diese Daten nicht angezeigt werden, besteht darin, das Terminal an Ihrem Ende zu verlassen und die Verbindung zu Ihrer Fernbedienung wiederherzustellen. Dies ist jedoch wahrscheinlich weitaus aufwändiger, als auf die Anzeige der gepufferten Daten zu warten.


10

Normalerweise starte ich die Ausgabe, lessdamit ich sie mit töten kann, lessanstatt den qSchlüssel zu benutzen .

$ cmd | less

Beispiel

$ cat /dev/urandom | less

   ss # 2

Nachdem Sie auf q+ geklickt haben, wird Enteres beendet und kehrt zu Ihrem normalen Terminal zurück, sodass es schön sauber bleibt.

Warum passiert das?

Das Problem, auf das Sie stoßen, besteht darin, dass Puffer (für STDOUT) mit der Ausgabe Ihrer Anzeige in die Warteschlange gestellt werden. Diese Puffer füllen sich so schnell, dass Sie sie nicht schnell genug unterbrechen können, um sie zu stoppen.

                                    ss # 1

Um diesen Effekt zu deaktivieren / einzuschränken, können Sie die STDOUT-Pufferung deaktivieren, wodurch die Verwendung etwas reaktionsschneller wird. stdbufSie müssen jedoch wahrscheinlich mit diesen Einstellungen spielen, um die gewünschten Ergebnisse zu erzielen . Um STDOUT zu entpuffern, können Sie diesen Befehl verwenden:

$ stdbuf -o0 <cmd>

Auf der Manpage finden Sie stdbufDetails zu den verfügbaren Optionen:

    If MODE is 'L' the corresponding stream will be line buffered.  This 
    option is invalid with standard input.

    If MODE is '0' the corresponding stream will be unbuffered.

    Otherwise MODE is a number which may be followed by one of the 
    following: KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so
    on for G, T, P, E, Z, Y.  In this case the corresponding stream will be 
    fully buffered with the  buffer  size  set  to  MODE
    bytes.

Um einen guten Überblick über die Funktionsweise des Puffers zu erhalten, empfehle ich einen Blick auf diesen Pixel Beat mit dem Titel: Puffern in Standard-Streams . Es enthält sogar schöne Bilder.

Verweise


Das ist sinnvoll , solange Sie anhängen erinnern |lessan cmd, was leider oft ich nicht. Wenn Sie ausgeführt werden cmd, müssen Sie noch warten, bis der Druck der berechneten Ergebnisse abgeschlossen ist, bevor Sie sie empfangen ^C.
rr

1
Das erklärt nicht wirklich, was los ist. Schließlich ist keine Pipe beteiligt. Auf welchen Puffer beziehen Sie sich also?
Gilles 'SO - hör auf, böse zu sein'

@ Gilles - Entschuldigung, der Puffer wäre der Puffer für den Bildschirm.
SLM

Welcher Puffer? Im Kernel? In xterm?
Gilles 'SO - hör auf, böse zu sein'

@ Gilles - gib mir eine Minute, ich suche die Details 8-)
slm

3

Es gibt mehrere Pufferebenen. Durch Drücken von Ctrl+ wird verhindert C, dass das Programm Daten an das Terminal sendet. Dies wirkt sich nicht auf Daten aus, die der Terminalemulator noch nicht angezeigt hat.

Wenn Sie Daten mit sehr hoher Geschwindigkeit anzeigen, kann das Terminal nicht mithalten und wird verzögert. Genau das ist hier der Fall: Das Anzeigen von Text ist viel teurer als das Erzeugen dieser Zufallszahlen. Ja, auch mit einer Bitmap-Schriftart - die Erzeugung von Zufallszahlen in kryptografischer Qualität ist im Vergleich spottbillig. (Ich habe es gerade auf meinem Rechner versucht und der X-Prozess hat die CPU mit xtermein paar Prozent ausgelastet, und cat(was der Zufallszahlengenerierung zugerechnet wird) erreicht kaum 1 Prozent. Und das mit einer Bitmap-Schriftart.)

Wenn Sie möchten, dass dies jetzt beendet wird, beenden Sie den Terminalemulator. Wenn Sie das nicht möchten, minimieren Sie zumindest das Fenster. Intelligente Terminal-Emulatoren (z. B. xterm) ordnen das Fenster nicht zu, wodurch die X-CPU-Zeit gespart wird, sodass der Müll schneller angezeigt wird. Der X-Server hat eine hohe Priorität, sodass sich dies erheblich auf die Reaktionsfähigkeit Ihres Computers auswirkt, während xterm die Daten im Hintergrund verarbeitet.

Wenn dies alles in einer Remote-Shell geschieht, ist die Verzögerung noch schlimmer, da die von erzeugten Daten catzuerst die SSH-Verbindung durchlaufen müssen. Ihre Presse von Ctrl+ muss Cauch über die SSH-Verbindung gehen; Die Priorität ist etwas höher (es wird außerhalb des Bandes gesendet), aber das dauert noch einige Zeit, während der sich mehr Output ansammelt. Es gibt keine Möglichkeit, Daten während der Übertragung zu unterdrücken, ohne die SSH-Verbindung zu beenden (was Sie tun können, indem Sie Enterdann auf drücken ~.).


Das Problem hängt mit SSH zusammen. Der STDOUT-Puffer sollte im interaktiven Modus nicht verwendet werden, SSH kann den interaktiven Modus jedoch nicht ordnungsgemäß verarbeiten. Obwohl eine Menge Ausgabe in der Transaktion hängen bleiben kann, ist es der SSH-Prozess, der Strg + C empfängt. Es liegt daher in seiner Verantwortung, die Ausgabe zu beenden, wenn es unmöglich ist, Strg + C an Remote zu übergeben.
user4674453

@ user4674453 Äh? Strg + C soll die lokale Ausgabe nicht beenden. Das ist überhaupt nicht seine Aufgabe. Es soll an die Remote-Seite übergeben werden, die den Remote-Prozess möglicherweise abbricht oder nicht.
Gilles 'SO- hör auf böse zu sein'

"Es soll an die entfernte Seite übergeben werden, die den entfernten Prozess möglicherweise abbricht oder nicht." - Das soll es auch nicht. KILL-Signale, von denen Strg + C eines ausgibt, sind nur für den lokalen Prozess bestimmt. Wenn es nicht für lokale Prozesse verwendet wird, ist der Begriff "Soll" überhaupt nicht anwendbar.
user4674453

@ user4674453 Nein. Strg + C ist kein Kill-Signal. Es ist ein Interruptsignal. Ihre Aufgabe ist es, zu einer interaktiven Eingabeaufforderung zurückzukehren. Es werden nur Programme beendet, die keine interaktive Eingabeaufforderung haben, zu der Sie zurückkehren können.
Gilles 'SO - hör auf böse zu sein'

"Es ist ein Interrupt-Signal." Es ist ein Argument, Befehl zu töten, daher ist es ein Tötungssignal. Manchmal wird es als POSIX-Signal bezeichnet, wenn Sie möchten. "Ihre Aufgabe ist es, zu einer interaktiven Eingabeaufforderung zurückzukehren. Sie beendet nur Programme, die keine interaktive Eingabeaufforderung haben, zu der sie zurückkehren können." Genau!!! Und SSH macht das nicht wie erwartet.
user4674453

1

Es sollte ausreichen , um einen Weg zu finden , killden catBefehl.
Für die folgenden Vorschläge benötigen Sie möglicherweise eine zweite offene SSH-Verbindung.

  • Selten CTRL+zkann es effektiver sein als CTRL+c: es kann schneller antworten. Danach setzen Sie den Befehl aus, mit dem Sie ihn beenden können, kill %1oder wie auch immer seine Auftragsnummer lautet.
    Dies in der Hoffnung, dass Sie immer noch in der Lage sind, alles auf dem Bildschirm zu lesen (ein überflutender zufälliger Binärtext kann Ihren Zeichensatz leicht durcheinander bringen). Wenn Sie das Fenster minimieren, ist das System wahrscheinlich schneller beim Lesen der Interrupt-Anforderung als beim Beenden des Prozesses,
    wie Gilles sich erinnert hat . Also aussetzen / unterbrechen, minimieren, etwas warten, wieder maximieren, kann auch eine Lösung sein.
    Natürlich erwarte ich über eine ssh-Verbindung, dass du allerdings etwas warten musst.

  • In einem anderen Terminal / einer anderen Sitzung können Sie fragen pgrep cat(ob cat der aufgerufene Befehl war), und feststellen, dass der cat-Prozess mehr Ihre CPU verwendet. Sie können es genauer identifizieren mit pstree:

    pgrep katze | awk '{print "pstree -sp" $ 1}' | sh | grep sshd

    antworte mit einer Ausgabe wie

    init (1) ───sshd (1062) ───sshd (22884) ───sshd (22951) ───bash (22957) ───cat (23131)

    In diesem Fall müssen Sie nur die PID der Katze töten: 23131 töten

Hinweis:


1

Ich hatte das gleiche Problem und war mit den Antworten hier nicht zufrieden, also habe ich tiefer gegraben. Andere haben bereits erwähnt, dass Ihr Befehl Daten schneller ausgibt, als Ihr ssh verarbeiten kann, sodass die Datenpuffer und -puffer nicht angehalten werden können.

Um dies zu beheben, vermeiden Sie das Puffern, indem Sie die Befehlsausgabe auf die maximale Geschwindigkeit drosseln, die Ihre SSH-Sitzung annehmen kann. Hierzu sind bereits Befehle vorhanden.

Ermitteln Sie zuerst Ihre maximale Sitzungsrate:

# Get transfer <TIME> of a large file (>10MB preferable)
/usr/bin/time -f "%e" cat <FILENAME>

# Get file <SIZE> in bytes
stat --printf="%s\n" <FILENAME>

# Calculate <RATE>
echo "<SIZE> / <TIME>" | bc

Zum Schluss drosseln Sie Ihre echten Befehle entsprechend.

<YOUR_COMMAND> | pv -qL <RATE>

Beispiel:

/usr/bin/time -f "%e" cat large_reference_file.txt
31.26

stat --printf="%s\n" cat large_reference_file.txt
17302734

echo "17302734 / 31.26" | bc
553510

# Throttle my command to 553510B/s
cat some_other_file.txt | pv -qL 553510

Möglicherweise möchten Sie die RATE ein wenig reduzieren, falls Ihre Verbindungsgeschwindigkeit von Zeit zu Zeit ein wenig sinkt. Wenn es abfällt, kehrt das Verhalten zum Problem zurück, einem nicht reagierenden Strg-C.

Optionaler gedrosselter Katzenalias:

# bash
alias tcat='tcat(){ cat $@ | pv -qL 400k ; }; tcat'

# tcsh
alias tcat 'cat \!* | pv -qL 400k'

# usage: tcat <FILENAME>

Jetzt funktioniert Strg-C wie erwartet und beendet die Ausgabe sofort, da nur sehr wenig oder gar nichts gepuffert ist.


catDie Ausgabe ist im Gegensatz zu anderer Software selten ein Problem. Der Autor hat es nur als Beispiel verwendet. Das Problem liegt normalerweise an der anderen Software, die möglicherweise nicht offensichtlich ist, wenn sie bereit ist, viel Ausgabe zu produzieren. Die Verwendung eines Präfix- oder Postfix-Befehls ist keine Lösung, da die Eingabe einige Zeit in Anspruch nimmt. Es wird keinen Gewinn im Ergebnis geben.
user4674453

0

Unter Linux gibt es eine Software, die genau dieses Problem löst (ein paar andere Dinge auch). Sie können es auch von einem Terminalemulator in Windows aus aufrufen (Sie scheinen Windows zu verwenden?).

Versuchen Sie mosh , einen Ersatz für die SSH-Binärdatei. Es funktioniert genau wie SSH (Sie können es mosh user@hostnamestattdessen tun ssh user@hostnameund es würde genau so funktionieren, wie Sie es erwarten, es wird sogar eine Authentifizierung mit privatem Schlüssel usw. durchgeführt.)

Grundsätzlich wird ein separater Prozess auf dem Server ausgeführt, der die Pakete puffert. Wenn Sie also bei mosh Strg + C drücken, wird dies an den Remote-Server weitergeleitet, der dann die zusätzlichen Informationen nicht mehr sendet. Außerdem wird das Ergebnis von Tastenanschlägen vorhergesagt, sodass Sie bei jedem Tastendruck einige Millisekunden Zeit sparen.

Nachteil: Derzeit ist es nicht möglich, mit mosh im Verlauf nach oben zu scrollen.

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.