Jaki jest cel opóźnionego zawieszenia (Ctrl-Y) w Bash?


30

Pełna część strony podręcznika użytkownika Bash, która ma zastosowanie, mówi tylko:

Jeśli system operacyjny, na którym działa bash, obsługuje kontrolę zadań, bash zawiera narzędzia do korzystania z niego. Wpisanie znaku wstrzymania (zazwyczaj ^ Z, Control-Z) podczas działania procesu powoduje, że proces ten zostaje zatrzymany i przywraca kontrolę do bash. Wpisanie znaku opóźnionego zawieszenia (zwykle ^ Y, Control-Y) powoduje zatrzymanie procesu, gdy próbuje on odczytać dane wejściowe z terminala, i sterowanie zostaje zwrócone do bash. Użytkownik może następnie manipulować stanem tego zadania, używając bg polecenia, aby kontynuować je w tlefgpolecenie, aby kontynuować na pierwszym planie, lub polecenie zabicia, aby go zabić. ^ Z zaczyna działać natychmiast i ma dodatkowy efekt uboczny, powodując odrzucenie oczekujących danych wyjściowych i typów.

Nigdy nie korzystałem Ctrl- Y; Właśnie się o tym dowiedziałem. Zrobiłem dobrze tylko z Ctrl- Z(zawiesić).

Próbuję sobie wyobrazić, co ta opcja jest dla . Kiedy to byłoby przydatne?

(Zauważ, że ta funkcja nie istnieje we wszystkich wariantach Uniksa. Jest obecna w Solarisie i FreeBSD, ale nie w Linuksie. Odpowiednie ustawienie to stty dsusp.)

Być może mniej subiektywnie: czy jest coś, co można osiągnąć Ctrl- Yczego nie da się osiągnąć równie łatwo Ctrl- Z?


@Gilles, choć wydaje się, że FreeBSD ma stty dsusp, nie udało mi się wysłać SIGTSTP po ^ Y (zrobiłem na Solarisie). Czy ty?
Stéphane Chazelas,

Odpowiedzi:


23

Z podręcznika 4BSD dla csh :

A ^Zdziała natychmiast i jest jak przerwanie w oczekującym wyniku, a nieprzeczytane dane wejściowe są odrzucane po ich wpisaniu. Istnieje inny specjalny klucz, ^Yktóry nie generuje sygnału STOP, dopóki program nie spróbuje go odczytać (2). Można to z łatwością wpisać, gdy przygotujesz kilka poleceń dla zadania, które chcesz zatrzymać po ich przeczytaniu.

Dlatego celem jest wpisanie wielu danych wejściowych podczas przetwarzania pierwszego i zatrzymanie zadania po ich zakończeniu.


Ten opis różni się nieznacznie od podręcznika bash. „... nie generuje sygnału STOP do momentu próby programu do czytania go. To brzmi jak wszystko w wejściu strumieniowo do^Y zostaną odczytane pomyślnie, a następnie, gdy ^Yjest trafiony proces zostanie zatrzymany. Czy czytam to prawda?
Wildcard

@Wildcard w moim teście na Mac OS X proces zostaje zatrzymany, zanim funkcja read () powróci (ale po wywołaniu read (), które zwróciło wykonanie Y), a po wznowieniu odbiera dane wejściowe sprzed ^ Y . Wydaje mi się, że skoro miał być używany, to byłby używany na początku linii, więc zachowanie w tym przypadku nie miałoby znaczenia. Podejrzewam, że w rzeczywistym kodzie jest zawieszony, gdy ^ Y zostałoby skopiowane do bufora odczytu procesu użytkownika.
Random832


Ale po wznowieniu procesu połączenie zakończy się powodzeniem i będzie zawierało dane wpisane wcześniej w terminalu ^Y, nawet jeśli wyrzekłeś się procesu i zamknąłeś terminal przed wznowieniem. Dobrze? ( „... po wznowieniu otrzymuje dane wejściowe sprzed ^ Y.” To właśnie miałem na myśli; zwykle nie zajmuję się kodem C.) :)
Wildcard

Tak. I wraca bez nowego wiersza na końcu, co jest niezwykłe w przypadku czytania w trybie kanonicznym [podobnie jak w przypadku wpisania tekstu i naciśnięcia ^ D raz] Podejrzewam, że nie zastanawiali się zbytnio o tej sprawie, ponieważ naprawdę jest przeznaczony do pisania na początku wiersza.
Random832

11

Powiedzmy, że istnieje wejście do odczytu i wykonywania w pętli. Przydatne może być pozostawienie zadania do zakończenia bieżącej instrukcji, którą oblicza, bez przerywania go, zanim wróci do wiersza poleceń w celu uzyskania nowej. Tak więc, aby zakończyć cykl. To z wdziękiem kończy pętlę i zapobiega jej ponownemu uruchomieniu, jeśli readjest ograniczona limitem czasu.


Ale jeśli to będzie próbować odczytać dane wejściowe z terminala W każdym razie, to zatrzymać w tym punkcie (i czekać na wejście) i można ^Zgo wtedy .
Wildcard,

Tak. Zobacz aktualizację.
Tomasz

Sprawdź jeszcze raz. @Wildcard
Tomasz

1
Ale jeśli upłynie limit czasu, czy nie skończy się również z gracją, jeśli nie zrobisz nic specjalnego?
Daniel Wagner,

1
Może. Ale może również trwać i wykonywać jakąś domyślną pracę.
Tomasz

4

Mogę wymyślić jeden scenariusz, w którym może być przydatny, ale jest to coś w rodzaju wymyślonego przypadku.

Załóżmy, że debugujesz skrypt zapisujący pliki tymczasowe, które chcesz przeanalizować, zanim zostaną usunięte w ramach procedury czyszczenia.

Możesz dodać read foogdzieś po zapisaniu plików (ale przed czyszczeniem), uruchom skrypt i naciśnij Ctrl- Ypodczas ich generowania. Nastąpi wyświetlenie monitu ze skryptem zawieszonym w tle, aby zrobić wszystko, co musisz zrobić, a następnie możesz fgpozwolić na zakończenie skryptu.


1
Wydaje się mało prawdopodobne, ponieważ skrypt i tak czeka na dane wejściowe. Możesz więc równie łatwo sprawdzić, czy monituje o podanie danych, a następnie zawiesić ^Z. Innymi słowy: po wpisaniu fgtrzeba będzie dać skrypt pewien wkład w każdym razie , zanim będzie ona kontynuowana. Stąd moje pytanie; Nadal nie widzę sensu ^Y. (Dziękuję za odpowiedź!) :)
Wildcard

2

Jedynym scenariuszem, jaki mogę wymyślić (a nawet nie uważam tego za bardzo przekonujące), jest to, że chcesz użyć polecenia typu polecenie z wyprzedzeniem. Powiedzmy, że uruchomione jest polecenie, które w przyszłości odczyta dane wejściowe. Następnie możesz ^ Y to, a następnie natychmiast wpisać następne polecenie powłoki, które chcesz wykonać, gdy uruchomione polecenie zawiesi się. Nie sądzę, że kiedykolwiek tak naprawdę używałem tego od kilku dekad używania BSD Unix.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.