Zakończyć zsh, ale pozostawić uruchomione zadania otwarte?

98

Właśnie przełączyłem się z bash na zsh.

W bash zadania w tle działają dalej po zamknięciu powłoki. Na przykład tutaj, dolphinkontynuuje działanie po exit:

$ dolphin .
^Z
[1]+  Stopped                 dolphin .
$ bg
[1]+ dolphin . &
$ exit

Tego właśnie chcę jako domyślnego zachowania.

W przeciwieństwie do tego zachowanie zsh polega na ostrzeganiu przed uruchomieniem zadań exit, a następnie zamknięciu ich, jeśli exitponownie. Na przykład tutaj, dolphinjest zamykane, gdy druga exitkomenda faktycznie wychodzi z powłoki:

 % dolphin .
^Z
zsh: suspended  dolphin .
 % bg
[1]  + continued  dolphin .
 % exit
zsh: you have running jobs.
 % exit 

Jak ustawić domyślne zachowanie zsh, takie jak bash?

Owen_R
źródło

Odpowiedzi:

173

Uruchom program z &!:

dolphin &!

&!( Lub równoważnie&| ) jest zsh specyficzne skrót zarówno tło i wyprzeć procesu, tak że wyjście z powłoki nie pozostawi uruchomiony.

Anko
źródło
2
Dla kompletności, czy możesz również wymienić, jak się go wyprzeć, gdy już się rozpoczął?
trusktr
@trusktr Jest inne pytanie dotyczące wyrzekania się procesu pierwszoplanowego . Myślę, że najlepiej przechowywać je oddzielnie dla zachowania przejrzystości. Wszystkim zainteresowanym konkretnie zsh zadałem pytanie na temat U&L SE o to, jak stworzyć szybszy przepływ pracy w celu rezygnacji z procesu pierwszoplanowego .
Anko
Podoba mi się to rozwiązanie i zaimplementuję je dla poszczególnych poleceń, ale wciąż szukam sposobu na zmianę domyślnego zachowania Zsh.
Vince
1
@Vince Czy masz na myśli zmianę domyślnego, aby zawsze wyrzekać się procesów działających w tle? Jeśli tak, możesz to zrobić za pomocą setopt nohuppliku ~/.zshrc. Wtedy uruchomienie polecenia w tle &zawsze go wyrzeknie. Chociaż domyślnie zsh nadal będzie przypominać ci, że masz uruchomione zadania, gdy próbujesz wyjść. Możesz to również wyłączyć za pomocą setopt nocheckjobs.
Anko,
@Anko Myślę, że setopt nocheckjobsrobi to, co chcę. Teraz znalazłem dostępne opcje w man zshoptions. Chciałbym wyłączyć ostrzeżenie. Wiem, kiedy mam procesy w tle i nie potrzebuję tego. Chciałbym, aby zamykał procesy w tle, chyba że zacząłem je od nohup. Obecnie używam tego z funkcją powłoki, która uruchamia PyCharm w tle z nohup. Kiedy piszę pycharm ., działa nohup charm $@ &. Nie zamyka się, gdy zamykam terminal, ale nadal otrzymuję ostrzeżenie i muszę exitdwukrotnie wpisać .
Vince
59

Z dokumentacji zsh :

HUP

... W zsh, jeśli podczas zamykania powłoki uruchomione jest zadanie w tle, powłoka przyjmie, że chcesz je zabić; w tym przypadku wysyłany jest specjalny sygnał o nazwie SIGHUP… Jeśli często uruchamiasz zadania, które powinny być kontynuowane nawet po zamknięciu powłoki, możesz ustawić tę opcję NO_HUP, a zadania w tle zostaną pozostawione same.

Po prostu ustaw NO_HUPopcję:

% setopt NO_HUP
Carl Norum
źródło
Jeśli nie chcesz ostrzeżenia, tak.
Carl Norum
30

I odkryli, że za pomocą kombinacji nohup, &i disownpracuje dla mnie, ponieważ nie chcę, aby trwale przyczyną pracy do uruchomienia gdy powłoka odszedł.

nohup <command> & disown

Chociaż tylko &pracował dla mnie bash, znalazłem przy użyciu tylko nohup, &czy disownna prowadzeniu poleceń, jak skrypt, który wywołuje polecenie run java, proces nadal zatrzymać, gdy powłoka jest zakończony.

  • nohuppowoduje, że polecenie ignoruje NOHUPi SIGHUPsygnalizuje z powłoki
  • & sprawia, że ​​proces przebiega w tle w subterminale
  • disownpo którym następuje argument (indeks numeru zadania na liście zadań) zapobiega wysyłaniu przez powłokę SIGHUPsygnału do procesów potomnych. Użycie disownbez argumentu powoduje, że domyślnie przyjmuje najnowsze zadanie.

Znalazłem informacje nohupi disownna tej stronie oraz &informacje w tej odpowiedzi SO .

ryanjdillon
źródło
5

Zwykle używam screendo utrzymywania pracy w tle.

1) Utwórz sesję screenową:

screen -S myScreenName

2) Uruchom swoje skrypty, usługi, demony lub cokolwiek innego

3) Zakończ (odłącz) sesję ekranową za pomocą

screen -d

lub skrót ALT+A then d


Po kilkuset latach - jeśli chcesz wznowić sesję (podłącz ponownie):

screen -r myScreenName

Jeśli chcesz wiedzieć, czy istnieje sesja ekranu, jej nazwę i stan (dołączony lub odłączony):

screen -ls

To rozwiązanie działa na wszystkich interpreterach terminala, takich jak bash, zsh itp. Zobacz także man screen

Aydin K.
źródło
Uwaga dla użytkowników MacOS, skrót klawiaturowy do odłączenia od ekranu to Control + A, a następnie D. Również to była moja jedyna opcja, gdy zostawiłem uruchomiony proces i przechodziłem na stdout, napisanie screen -d tam nie pomogło.
Bishoy,
Fajnie, ale nie ma to nic wspólnego z Q, który dotyczy w szczególności tego, jak utrzymać uruchomione zadania bg podczas wychodzenia z ZSH.
RichieHH