Problem
Wykonuję polecenie, które wysyła DUŻO informacji przez SSH. Na przykład głupio dodaję informacje debugowania w pętli, która wykonuje się milion razy, lub po prostu uruchamiam cat /dev/urandom
kopnięcia.
Terminal jest zalany informacjami.
Chcę zakończyć polecenie jak najszybciej i naprawić mój program. Nie obchodzi mnie, co drukuje. Chodzi o to, że naciskam Ctrl+ CASAP (w powyższym przykładzie nacisnąłem go natychmiast po uruchomieniu polecenia), ale nadal zajmuje dużo czasu, aby wydrukować wszystkie informacje, których nawet nie potrzebuję .
Co próbowałem
Próbowałem naciskać Ctrl+ Ctak mocno, że przyniosło to dziwne rezultaty, gdy terminal w końcu dogonił:
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
Przeczytałem również o Ctrl+, Sktóry najwyraźniej służy do powiedzenia terminalowi „zatrzymaj wyjście, muszę nadrobić zaległości”, ale najwyraźniej nic nie robi.
Różne szczegóły
Nie chciałbym zmieniać polecenia, które uruchamiam, aby w każdej sytuacji móc się uratować, nawet jeśli nie pamiętam, że uruchamiany przeze mnie program może tak się skończyć.
Mój klient SSH działa na Cygwin ( CYGWIN_NT-6.1-WOW64 luna 1.7.30(0.272/5/3) 2014-05-23 10:36 i686 Cygwin
) w MinTTY z typem terminala ustawionym na xterm-256color
.
Serwer SSH działa na Debian ( Linux burza 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686 i686 i686 GNU/Linux
).
Ctrl-O
, co oznacza „odrzucić wszelkie dane wyjściowe zapisane na tym terminalu”.-j
opcją, aby włączyć przewijanie skoku. Podstawowym problemem jest to, że pilot może wysyłać dane szybciej niż okno terminalu może je wyświetlić - domyślnie musi bitbltować zawartość okna za każdym razem, gdy drukowany jest nowy wiersz. Do momentu odebrania Ctrl-C przez zdalny system można zbuforować dużo danych, a program terminalowy spróbuje wyświetlić je wszystkie..bashrc
?Odpowiedzi:
Niektóre z tych danych wyjściowych będą buforowane. Wysyłasz Ctrl+ Cdo zdalnego końca, który przerywa działający program. Program istnieje, a powłoka wysyła znaki, aby ponownie wyświetlić monit. Przed wyświetleniem monitu na ekranie zostaną wyświetlone wszystkie dane, które zostały buforowane i są już w drodze do Ciebie.
Pytasz, czy program się zatrzyma, a przesyłane dane jakoś znikną. To nie może się zdarzyć, ponieważ jest już w drodze.
Jedynym sposobem, aby upewnić się, że nie widzisz tych danych, jest wyjście z terminala na swoim końcu, a następnie ponowne połączenie się z pilotem - ale to prawdopodobnie znacznie więcej wysiłku niż czekanie na wyświetlenie buforowanych danych.
źródło
Zwykle uruchamiam dane wyjściowe,
less
aby móc je zabić zaless
pomocą qklucza.Przykład
Po wciśnięciu q+ Enter, wyjdzie i wróci do normalnego terminala, pozostawiając ładnie i czysto.
Dlaczego tak się dzieje?
Problem, który napotykasz, polega na tym, że istnieją bufory (dla STDOUT), które są ustawione w kolejce z wyjściem twojego wyświetlacza. Bufory te zapełniają się tak szybko, że nie można przerwać ich wystarczająco szybko, aby je zatrzymać.
Aby wyłączyć / ograniczyć ten efekt, możesz wyłączyć buforowanie STDOUT, co powinno sprawić, że będzie nieco bardziej responsywne
stdbuf
, ale prawdopodobnie będziesz musiał grać z tymi ustawieniami, aby uzyskać pożądany efekt . Aby cofnąć buforowanie polecenia STDOUT, możesz użyć tego polecenia:Strona
stdbuf
podręcznika ze szczegółowymi opcjami do dyspozycji:Aby uzyskać dobre tło na temat działania buforowania, gorąco polecam przyjrzeć się temu artykułowi Pixel Beat zatytułowanemu: buforowanie w standardowych strumieniach . Zawiera nawet ładne zdjęcia.
Bibliografia
źródło
|less
docmd
, co niestety często nie. Jeśli uruchomiszcmd
, nadal musisz poczekać, aż zakończy się drukowanie wyników obliczonych przed otrzymaniem^C
.Istnieje kilka poziomów buforowania. Naciśnięcie Ctrl+ Cpowoduje, że program nie emituje danych do terminala. Nie wpływa to na dane, których emulator terminala jeszcze nie wyświetlał.
Gdy wyświetlasz dane z bardzo dużą prędkością, terminal nie może nadążyć i będzie opóźniony. Oto, co się tutaj dzieje: wyświetlanie tekstu jest o wiele droższe niż tworzenie liczb losowych. Tak, nawet w przypadku czcionek bitmapowych - tworzenie liczb losowych o jakości kryptograficznej jest tanie w porównaniu z innymi. (Właśnie wypróbowałem na swoim komputerze, a proces X nasycił procesor,
xterm
biorąc kilka% icat
(przy czym generowane są liczby losowe) ledwo osiągając 1%. I to z czcionką bitmapową.)Jeśli chcesz to teraz zatrzymać, zabij emulator terminala. Jeśli nie chcesz tego robić, przynajmniej zminimalizuj okno; inteligentne emulatory terminali (takie jak xterm) nie odwzorowują okna, co oszczędza czas procesora X, więc śmieci zostaną szybciej wyświetlone. Serwer X ma wysoki priorytet, więc będzie to miało duży wpływ na szybkość reakcji twojego komputera, gdy xterm przetwarza dane w tle.
Gdy wszystko to dzieje się w zdalnej powłoce, opóźnienie jest jeszcze większe, ponieważ wytworzone dane
cat
muszą najpierw przejść przez połączenie SSH. Wciśnięcie Ctrl+ Cmusi również przejść przez połączenie SSH; ma nieco wyższy priorytet (jest wysyłany poza pasmem), ale nadal zajmuje to trochę czasu, podczas którego gromadzi się więcej mocy wyjściowej. Nie ma sposobu, aby ukryć przesyłane dane poza zamknięciem połączenia SSH (co można zrobić, naciskając Enterwtedy~.
).źródło
Powinno wystarczyć, aby znaleźć drogę do
kill
tejcat
komendy.W przypadku poniższych propozycji może być konieczne otwarcie drugiego połączenia ssh.
Rzadkość CTRL+zmoże być bardziej skuteczna niż CTRL+c: może odpowiadać szybciej. Następnie zawiesisz polecenie, za pomocą którego możesz go zabić
kill %1
lub pod jakimkolwiek numerem zadania.Ma to nadzieję, że nadal będziesz w stanie odczytać cokolwiek z ekranu (zalany losowy tekst binarny może łatwo zepsuć zestaw znaków).
Jak zapamiętał Gilles, jeśli zminimalizujesz okno, prawdopodobnie system szybciej odczyta żądanie przerwania niż ty zabijesz proces. Więc zawieszenie / przerwa, zminimalizowanie, poczekaj chwilę, zmaksymalizuj ponownie, może być również rozwiązaniem.
Oczywiście poprzez połączenie ssh oczekuję, że musisz jednak poczekać trochę czasu.
W innym terminalu / sesji możesz zapytać
pgrep cat
(czy polecenie cat zostało wywołane) i określić, czy proces cat używa więcej twojego procesora. Możesz go zidentyfikować bardziej precyzyjnie za pomocąpstree
:pgrep cat | awk '{print "pstree -sp" $ 1}' | sh | grep sshd
odpowiedz z wynikiem takim jak
init (1) ───sshd (1062) ───sshd (22884) ───sshd (22951) ───bash (22957) ───cat (23131)
W takim przypadku po zabiciu kota PID: zabij 23131
Uwaga:
less
jest bezpieczniejszy.źródło
Miałem ten sam problem i nie byłem zadowolony z odpowiedzi tutaj, więc zagłębiłem się głębiej. Inni wspominali już, że twoje polecenie wysyła dane szybciej niż ssh może zająć, więc buforów danych i buforów nie można zatrzymać.
Aby rozwiązać ten problem, unikając buforowania, ograniczając wydajność polecenia do maksymalnej prędkości, jaką może przyjąć sesja ssh, istnieją już takie polecenia.
Skonfiguruj, najpierw sprawdź maksymalną stawkę sesji:
Na koniec odpowiednio dudź swoje prawdziwe polecenia.
Przykład:
Możesz nieco zmniejszyć RATE, na wypadek, gdyby twoja prędkość połączenia nieco spadała od czasu do czasu. Jeśli spadnie, zachowanie powróci do wydania, niereagującego ctrl-c.
Opcjonalny alias kota z przepustnicą:
Teraz ctrl-c działa zgodnie z oczekiwaniami, natychmiast zabijając dane wyjściowe, ponieważ bardzo mało, jeśli w ogóle, jest buforowane.
źródło
cat
wyjście rzadko stanowi problem, w przeciwieństwie do innych programów. Autor wykorzystał to tylko jako przykład. Problem jest zwykle spowodowany przez inne oprogramowanie, które może nie być oczywiste, jeśli jest skłonny do wytworzenia dużej ilości danych wyjściowych. Użycie dowolnego rodzaju prefiksu lub komendy postfix nie jest rozwiązaniem, ponieważ jego wpisanie zajmuje trochę czasu. Wynik nie przyniesie żadnego zysku.W systemie Linux jest oprogramowanie, które rozwiązuje dokładnie ten problem (kilka innych rzeczy). Możesz także wywołać go z emulatora terminali w systemie Windows (wydaje się, że używasz systemu Windows?).
Wypróbuj mosh , zamiennik pliku binarnego SSH. Działa dokładnie tak, jak SSH (możesz to zrobić
mosh user@hostname
zamiastssh user@hostname
i działałoby dokładnie tak, jak się spodziewasz, będzie nawet przeprowadzać uwierzytelnianie klucza prywatnego itp.Zasadniczo uruchamia oddzielny proces na serwerze, który buforuje pakiety. Więc kiedy naciśniesz Ctrl + C na mosh, przekaże to do zdalnego serwera, który następnie przestanie wysyłać dodatkowe informacje. Ponadto będzie również przewidywać wynik naciśnięć klawiszy, co pozwoli zaoszczędzić kilka milisekund za każdym razem, gdy naciśniesz klawisz.
Wada: Obecnie nie można przewijać historii w górę podczas używania mosh.
źródło