Jak mogę zrobić Ctrl-Z i bg jednym naciśnięciem klawisza, aby proces był kontynuowany w tle?

25

Śledzę ten schemat zawieszania zadania, a następnie pozwalam mu zbyt często kontynuować Ctrl-Z bgsekwencję.

Zastanawiałem się, czy jest jakiś sposób na skompresowanie tego do pojedynczego naciśnięcia klawisza?

Moja skorupa jest zsh

Evgeniy Dolzhenko
źródło
Chcę powiedzieć, że prawdopodobnie jest mocno zakodowany. Ale nie jestem w 100%
Chad Harrison
Jasne, że tak, ale znalazłem eleganckie rozwiązanie, dziękuję superuser.com/a/161922/35223
Evgeniy Dolzhenko

Odpowiedzi:

24

Ctrl+ ZSekwencji obsługiwane przez terminal nie przez powłokę. (Przydatne tło: Jaka jest dokładna różnica między „terminalem”, „powłoką”, „tty” i „konsolą”? )

Tylko niewielki, nierozszerzalny zestaw funkcji można przypisać do klawisza w terminalu . Można dostosować klawisze powiązane z tymi funkcjami, ale nie można dodawać innej funkcji. Funkcje te dzielą się na trzy kategorie:

  • Edycja wiersza poleceń w programach, które nie zapewniają własnego (tryb kanoniczny, zwany także trybem gotowanym (w przeciwieństwie do trybu raw), którego rzadko używasz w praktyce): koniec pliku ( eof, Ctrl+ D), koniec linii ( eol, Ctrl+ M), usuń znak w lewo ( erase, Ctrl+ H), usuń słowo w lewo ( werase, Ctrl+ W), usuń wiersz ( kill, Ctrl+ U).
  • Ręczna kontrola przepływu: stop( Ctrl+ S), start( Ctrl+ Q). Przydatny tylko w przypadku starych terminali szeregowych, które upuszczały znaki, gdy terminal nie był w stanie nadążyć za komputerem lub odwrotnie.
  • Sygnalizacja: przerwanie ( intr, Ctrl+ C), wymuszenie wyjścia ( quit, Ctrl+ \), zawieszenie ( Ctrl+ Z).

Niektóre systemy, w tym Linux, rozszerzają tę listę, ale nigdy nie widziałem takiego zawierającego tło. Zauważ, że wymagałoby to obsługi zarówno w sterowniku terminala w jądrze, jak i w emulatorze terminala. Musisz więc zadowolić się zawieszeniem, które wysyła do zadania pierwszego planu sygnał SIGTSTP . To uruchamia SIGCHLD w procesie nadrzędnym lidera zadania na pierwszym planie, którym jest zwykle powłoka. Gdy powłoka otrzymała SIGCHLD, wywołuje, waitpidaby dowiedzieć się, dlaczego została powiadomiona, a po wykryciu, że zadanie w tle zostało zawieszone, wyświetla powiadomienie (np. [1] + 12345 suspended mycommand) I nowy monit.

Możesz zaprogramować powłokę, aby wysyłała SIGCONTsygnał do zadania na pierwszym planie. Nie sądzę, aby zsh miał do tego haczyk, trzeba by załatać kod źródłowy. I nie ma sposobu, aby zsh wiedział, czy naprawdę chciałeś przerwać program (ups, ten program może robić coś złego, pozwól mi go zawiesić na czas rozwiązywania) lub w tle.


To, co robię, to ustawić sekwencję klawiszy Ctrl+ Zw Zsh, aby ustawić tło dla bieżącego zadania ( %%). W ten sposób mogę wysłać zadanie pierwszoplanowe do tła, naciskając Ctrl+ Z Ctrl+ Z. W tym momencie robię Ctrl+ Zcoś innego, co jest użyteczne, gdy bieżący wiersz wejściowy nie jest pusty (więc nie wróciłem z podprocesu): „zawieszam” bieżący wiersz wejściowy, pozwalając mi wpisać inne polecenie , po czym przerywana linia jest ponownie umieszczana w buforze wejściowym.

fancy-ctrl-z () {
  if [[ $#BUFFER -eq 0 ]]; then
    bg
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z
Gilles „SO- przestań być zły”
źródło
Gilles, to niesamowicie kompletna, edukująca i przemyślana odpowiedź, której nie mogłem się spodziewać! Dziękuję bardzo!
Evgeniy Dolzhenko
2

^ z ^ z jak zsh powyżej jest możliwe w bash, choć jest trochę niechlujny i nie uruchamiałem tego zbyt długo:

  • Do twojego .inputrc dołącz mapowanie "\C-z": "bg\n"
  • Do zmiennej bash PS0 należy dołączyć „$ (stty susp ^ z)”
  • Do zmiennej bash PROMPT_COMMAND należą „stty susp ^ @”

więc ^ z dla zawieszenia jest włączane po uruchomieniu polecenia, a następnie wyłączane dla monitu bash.

JohnLittle
źródło
1

Więc znalazłem rozwiązanie, nie dokładnie to, czego chcę, ale do cholery blisko stąd /superuser//a/161922/35223

W pustym wierszu polecenia działa bg (tak, że Ctrl + Z Ctrl + Z zawiesza program i natychmiast wznawia go w tle).

Evgeniy Dolzhenko
źródło
Zauważę, że wymaga to zsh; nie jest obsługiwany w bash. (w każdym razie po wyjęciu z pudełka)
Kevin M
@KevinM Możesz napisać analogiczną funkcję w bash (przynajmniej w podstawowej wersji Ctrl+Zwywołującej bg, nie jestem pewien, czy wykryję niepustą linię wejściową).
Gilles 'SO - przestań być zły'
0

Czy te polecenia, które chcesz uruchomić na pierwszym planie, a następnie przełączyć na tło? Nie wiem, czy jest na to prostszy sposób. Ale jeśli chcesz na początku uruchamiać polecenia, które będą w tle, możesz po prostu dodać znak ampersand na końcu wiersza. np. ping google.com &zacznie pingować w tle; nie będziesz mógł z nim wchodzić w interakcje, chyba że napiszesz fg.

ośmiornica
źródło
1
Dzięki, problem polega na tym, że czasami nie masz pojęcia, ile czasu zajmie wykonanie polecenia, więc działaj interaktywnie, a potem zdaj sobie sprawę, że lepiej pozwolić, aby kontynuowało się w tle. Przyjęta odpowiedź działa dla mnie cuda, wykorzystując ją codziennie!
Evgeniy Dolzhenko
Dzięki za odpowiedzi. Przyjęta odpowiedź jest całkiem fajna!
octern