Jak utrzymać działanie procesów po zakończeniu sesji ssh?

644

Powiedzmy, że uruchamiam kilka procesów z sesji ssh. Czy można zakończyć sesję ssh, utrzymując procesy uruchomione na zdalnym komputerze?

Olivier Lalonde
źródło
2
Powiązane: unix.stackexchange.com/questions/4004/…
Anton Tarasenko

Odpowiedzi:

750

Powinieneś poszukać nowoczesnych alternatyw, takich jak tmux.

tmuxjest lepszy screenod wielu powodów, oto tylko kilka przykładów:

  • Windows można przenosić między sesjami, a nawet łączyć z wieloma sesjami
  • Okna można podzielić poziomo i pionowo na szyby
  • Obsługa kolorowych terminali UTF-8 i 256
  • Sesjami można sterować z poziomu powłoki bez potrzeby wchodzenia w sesję

Podstawowa funkcjonalność

Aby uzyskać taką samą funkcjonalność, jak wyjaśniono w odpowiedzi na zalecenie screen, należy wykonać następujące czynności:

  • ssh do zdalnego komputera
  • zacznij tmuxod wpisania tmuxdo powłoki
  • rozpocznij proces, który chcesz w rozpoczętej tmuxsesji
  • opuść / odłącz tmuxsesję, wpisując Ctrl+, ba następnied

Możesz teraz bezpiecznie wylogować się ze zdalnego komputera, proces będzie nadal działał w środku tmux. Gdy wrócisz ponownie i chcesz sprawdzić status swojego procesu, możesz użyć go tmux attachdo dołączenia do tmuxsesji.

Jeśli chcesz mieć wiele sesji działających obok siebie, powinieneś nazwać każdą sesję za pomocą Ctrl+ bi $. Możesz uzyskać listę aktualnie uruchomionych sesji za pomocą tmux list-sessions, teraz dołącz do uruchomionej sesji za pomocą polecenia tmux attach-session -t 0.

tmuxpotrafi robić znacznie bardziej zaawansowane rzeczy niż obsługa pojedynczego okna w jednej sesji. Aby uzyskać więcej informacji, zajrzyj na stronę GitHubman tmux lub tmux . W szczególności tutaj jest FAQ na temat głównych różnic między screeni tmux.

tongpu
źródło
4
@CraigM Użyj screen -x -r [screenname]lub screen -rxw skrócie, jeśli masz tylko jedną sesję ekranu. Umożliwia to dołączenie istniejącej instancji ekranu.
Lekensteyn,
5
Ta rada pomogła mi z tym samym problemem, ale myślę, że zawiera literówkę. Jestem pewien, że musisz wpisać, Ctrl-ba następnie dopuścić / odłączyć tmuxsesję. Z pewnością tak jest w przypadku wersji tmuxna moim Ubuntu 12.04.
cxrodgers
17
Popełniłem błąd, wykonując powyższe instrukcje. Podzielę się nim, jeśli ktoś popełni ten sam błąd: zacząłem tmux w powłoce własnego komputera zamiast w powłoce komputera zdalnego. Tmux należy uruchomić w powłoce komputera zdalnego.
Mert Nuhoglu,
5
Ekran jest teraz opracowywany ponownie: lists.gnu.org/archive/html/screen-devel/2014-04/msg00024.html Czy możesz zaktualizować swoją odpowiedź?
muru
4
Możesz też uruchomić tmux detachzamiast pisaćctrl-b d
Andrew,
305

Opcja 1: nohup

Najlepszy sposób jest często najprostszy.

nohup long-running-command &

Został stworzony specjalnie do tego, nawet loguje standardowe wyjście nohup.log.

man nohup

Opcja 2: bg

Jeśli chcesz „uruchomić” niektóre już uruchomione zadania, najlepszym rozwiązaniem jest Ctrl+, Za następnie uruchomienie

bg

aby umieścić ostatnie zawieszone zadanie w tle, umożliwiając mu kontynuowanie działania.

W takim razie szybki disownpowinien kontynuować proces po wylogowaniu.

screeni inni mogą to zrobić, ale nie po to są. Polecam nohupdla zadań, o których wiesz, że zamierzasz zostawić za sobą, a także bgdla zadań, które już uruchomiłeś i nie chcesz ponownie zaczynać.

Pamiętaj, że oba są specyficzne dla bash. Jeśli nie używasz bash, polecenia mogą być inne.

Coteyr
źródło
4
Poleciłbym to zrobićdisown -h
Michele
co ciekawe screen i tmux nie działają dla górnika, ale działa no no
Yasin Okumuş
1
bg+ disownnie działało dla mnie. Miałem uruchomiony skrypt wdrażania. Zapomniałem uruchomić w tmuxie i musiałem wcześniej wyjść na spotkanie. Skrypt nieprzerwanie wysyła informacje o postępie do powłoki. ctrl+zzatrzymał proces, przywracając mnie do szału. bgwznowił proces, ale wznowił także wysyłanie stanu do bash, uniemożliwiając zobaczenie, co piszę. Jednak disownpolecenie wywołało „disown: current: no such job”
BrianHVB,
to nie działało dla mnie z julia myFile.jljakiegokolwiek powodu. Tmux działa i jest świetny.
kilgoretrout
To zadziałało dla mnie, dziękuję bardzo
Chad
207

Możesz to zrobić za pomocą screen.

Wpisz, man screenaby dowiedzieć się więcej lub przeczytaj tę stronę podręcznika użytkownika .

Prosty scenariusz:

  • ssh do twojego zdalnego urządzenia. Wpisz screenNastępnie uruchom żądany proces.

  • Naciśnij Ctrl- Anastępnie Ctrl- D. Spowoduje to „odłączenie” sesji ekranu, ale pozostawi procesy uruchomione. Możesz teraz wylogować się ze zdalnego skrzynki.

  • Jeśli chcesz wrócić później, zaloguj się ponownie i wpisz. screen -rTo „wznowi” sesję ekranu i zobaczysz wynik swojego procesu.

Lincoln
źródło
32
Zazwyczaj nazywam swoje sesje ekranowe za pomocą, screen -S nameaby ułatwić późniejsze połączenie z właściwą.
David Oneill
Link nie działa
Gab 是 好人
1
Osobiście pracuję nad pudełkiem bez żadnego oprogramowania do kontroli pakietów. Po spędzeniu około pół godziny na budowaniu zależności dla TMUX (z którymi osobiście mam doświadczenie i lubię) ze źródła, stało się jasne, że ekran był dla mnie lepszym i prostszym rozwiązaniem. TL; DR: optymalne rozwiązanie tego problemu zależy od przypadku użycia, maszyny i czasu potrzebnego na skonfigurowanie. Dzięki za tę odpowiedź :)
Max von Hippel
Połączenie z screen -Sprzed wyjazdem i screen -rpo powrocie jest niesamowite!
Meloman
Dzięki za to. To rozwiązanie działało dla mnie, podczas gdy tmux nie działał (używam wersji bash dla Windows, gdy ssh'ing na maszynę linux)
Michael Sorensen
83

Screen and nohup to lepszy sposób, ale jeśli musisz odłączyć proces, który już działa bez screena lub nohup, możesz uruchomić polecenie disown.

disown [-ar] [-h] [jobspec… |pid… ]

Bez opcji usuń każdy typ zadania z tabeli aktywnych zadań. Jeśli -hpodano opcję, zadanie nie jest usuwane z tabeli, ale jest oznaczane, aby SIGHUP nie był wysyłany do zadania, jeśli powłoka otrzyma SIGHUP. Jeśli specyfikacja zadania nie jest dostępna i nie podano-a ani -ropcji ani , wówczas używane jest bieżące zadanie. Jeśli nie podano specyfikacji zadania , -aopcja oznacza usunięcie lub zaznaczenie wszystkich zadań; -ropcja bez jobspec argumentu ogranicza działanie z prowadzeniem pracy.

Za pomocą disown możesz zamknąć terminal i uruchomić proces na komputerze.

bassgey
źródło
10
To także mój ulubiony sposób na zrobienie tego. Często używamdisown -a && exit
Stefano Palazzo
1
Doskonały. To piękne polecenie i zasługuje na wszystkie entuzjastyczne opinie!
Greg
8
jedno słowo ostrzeżenia, zatrzymałem uruchomiony proces z Ctrl-Z i nie uruchomiłem go w tle przed wywołaniem disowni to go zabiło.
HDave
3
Może ulec awarii, jeśli chce pisać do terminala. Przekierowanie wyjścia uruchomionego procesu nie jest tak łatwe. Lepiej zacząć poprawnie bez nohup.
jiggunjer
2
To dobra odpowiedź, ponieważ bezpośrednio odpowiada na pytanie. Autor pytania zapytał, co zrobić po wykonaniu kilku długich poleceń. Większość tych odpowiedzi informuje, co należy zrobić przed wykonaniem poleceń.
q0rban
53

Utknąłem w dużym mv, więc nie byłem w stanie zatrzymać procesu, ekranu konfiguracji, a następnie uruchomić go ponownie. Udało mi się wyjść z sesji ssh z uruchomionym procesem, wykonując zasadniczo następujące czynności:

  1. ssh [serwer]
  2. Komenda
  3. Ctrl+Z
  4. bg
  5. disown [proces pid opcjonalny, domyślnie trwa]
  6. wyjście

Krok 3 wstrzymuje bieżący proces (np. Moje polecenie „mv”).
Krok 4 umieszcza wstrzymany proces w tle i wznawia go.
Krok 5 pozwala odrzucić proces. ** Aby uzyskać listę zadań, po prostu wpisz jobswcześniej.


** Jeśli chodzi o disown (z podręcznika bash):

disown [-ar] [-h] [jobspec ... | pid ... ]
              Without  options,  remove  each jobspec from the table of active
              jobs.  If jobspec is not present, and neither the -a nor the  -r
              option  is  supplied, the current job is used.  If the -h option
              is given, each jobspec is not removed from  the  table,  but  is
              marked  so  that  SIGHUP  is  not  sent  to the job if the shell
              receives a SIGHUP.  If no jobspec is  supplied,  the  -a  option
              means  to  remove or mark all jobs; the -r option without a job‐
              spec argument restricts operation to running jobs.   The  return
              value is 0 unless a jobspec does not specify a valid job.
Chaos
źródło
2
Wbudowane są zawsze moim pierwszym wyborem :) THX
ken_oy
Ta odpowiedź powinna być oznaczona jako właściwa. Instalacja i przyzwyczajenie się do ekranu w celu rozwiązania tego problemu jest przesadzone.
Ulrich-Lorenz Schlüter
Jest to bardzo pomocne, gdy już uruchomiłeś dowolną komendę i która działa długo. Zakończenie i rozpoczęcie sesji TMUX zajmie trochę czasu
Deepali Mittal
1
@ tom-brossman: Uważaj na niepotrzebne zmiany, takie jak ta ! W przypadku wywołania bez specyfikacji zadania disownwbudowane polecenie działa na ostatnie zadanie w tle.
David Foerster,
22

Istnieją dwa główne programy, których można używać do utrzymywania programów i stanu terminala przez wiele połączeń ssh. Są one ekranowe (zasiedziałe, ale niestety nieobsługiwane. Najwyraźniej są teraz aktywnie rozwijane ) i tmux (nowsze, aktywnie utrzymywane). Byobu to interfejs, który może działać na swoich systemach i zapewnia dodatkowe informacje o stanie Ubuntu. W nowych instalacjach użyje tmux jako backendu, jeśli masz starszą instalację byobu i istniejącą konfigurację, zachowa poprzedni backend, czy to screen czy tmux.

Byobu

Byobu można zainstalować na komputerze, robiąc to na maszynie opartej na Debianie:

sudo aptitude install byobu

Używając mniam, robisz

su -c 'yum install byobu'

Możliwe jest również zainstalowanie byobu w innych dystrybucjach.

Korzystanie z Byobu

Możesz uruchomić byobu, uruchamiając byobusię na hoście po połączeniu za pomocą ssh. To da ci powłokę, która wygląda następująco:

image-byobu

Możesz także używać Byobu Terminal na komputerze Ubuntu z opcją -X i łatwo mieć doskonale działające byobu.

Stosowanie:

Zacznij byobu, pisząc byobu.

Możesz nacisnąć F2, aby utworzyć nowe okno w ramach bieżącej sesji, F3-F4, aby przełączać się między różnymi oknami.

Najlepsze w byobu jest to, że nie musisz zabijać procesów uruchomionych w terminalu, aby opuścić terminal. Możesz po prostu wysłać screen / tmux (szkielet byobu) do tła i wznowić następnym razem:

  • Aby wyjść z Byobu i utrzymywać go w ruchu (odłącz), naciśnij klawisz F6.
  • Następnym razem, kiedy przyjdziesz, po prostu byobuidź i powróć tam, gdzie byłeś.

    byobu-detach-attach

Możesz także tworzyć różne sesje Byobu przez byobu -S session1i tak dalej. Po powrocie możesz połączyć się z jednym z nich.

Możesz zrobić znacznie więcej, używając Byobu. Użyj tego! Niektóre ostateczne przewodniki są tutaj lub tutaj .

SiddharthaRT
źródło
Próbowałem użyć byobu z sesji opartej na PuTTY do mojego systemu Ubuntu, ale linia statusu jest powtarzana i przewijana na wyświetlaczu. Mimo że odłączył się poprawnie po naciśnięciu F6, nie było to użyteczne rozwiązanie w mojej konfiguracji.
jfmessier,
1
@jfmessier To dlatego, że PuTTY nie bierze dobrze ncurses (w zasadzie utf-8). Można wyeliminować ten problem, śledząc ten wątek - stackoverflow.com/questions/10731099/…
SiddharthaRT
To jest niesamowite! 1. daje mi kolorowy monit bash, którego nie mogę włączyć z bash jako domyślną powłoką i 2. Mogę uruchomić 2 boty w tym samym czasie i nadal mam inny terminal do pracy! @ SiddharthaRT zasłużyłeś na głosowanie!
Dev
18

Nie możesz tego zrobić po rozpoczęciu procesu, musisz skonfigurować rzeczy przed uruchomieniem długiego zadania.

Możesz używać nohup, ale współczesna mądrość sugeruje używanie screena lub byobu jako loginu, abyś mógł odłączyć i pozostawić sprawy uruchomione.

Zaletą ekranu jest to, że można odłączyć od jednego komputera i podłączyć go ponownie do drugiego, co jest przydatne, jeśli chcesz sprawdzić procesy działające długo po zakończeniu dnia roboczego.

Tutaj znajduje się uzasadniony przewodnik dla początkujących .

byobu umieszcza łatwy w użyciu interfejs na górze ekranu z menu itp. Jest to również bieżąca implementacja screena na nowszym Ubuntu. F2, aby uruchomić nowy terminal F3 / F4, aby przełączać się tam iz powrotem, a F6, aby się rozłączyć. Wpisz polecenie exit, aby faktycznie zakończyć terminale na stałe.

Richard Holloway
źródło
byobu używa tmux w dzisiejszych czasach ..
Scott
12
„Nie możesz tego zrobić po rozpoczęciu procesu, musisz skonfigurować wszystko, zanim uruchomisz długo działające zadanie”. - nie, możesz tego użyć disown. Zobacz odpowiedź @ bassgey
Rich
1
po walce o naukę ekranu i tmuxa .... Byobu przyniósł mi łzy do oczu
HDave
disowna w razie potrzeby wystarczy Ctrl-z, bgaby pobrać go z aktywnego terminala i w tle. Potem disown.
mimoralea
8

Hej, podczas gdy zgodziłem się, że ekran jest najbardziej efektywną opcją. Możesz użyć vncserver, a następnie rozpocząć na nim proces.

Również jeśli twoim jedynym interesem jest uruchomienie procesu i nie musisz go przejmować, a co najważniejsze, nie byłeś świadomy, że będziesz musiał zamknąć sesję i proces już działa, nie będziesz miał szczęścia, jeśli użyłeś bash jako powłoki

Najpierw musisz wysłać proces do tła, naciskając Ctrl + Z, a następnie bg% 1 (liczba zależy od numeru zadania, zwykle jest to 1, ale możesz łatwo wyciągnąć listę za pomocą zadań poleceń)

Na koniec wywołaj polecenie disown (po którym następuje jobid ... tak samo jak w przypadku polecenia bg)

Spowoduje to usunięcie relacji rodzic-dziecko między powłoką a procesem działającym w tle, zapobiegając jej śmierci po zakończeniu działania powłoki.

Jorge Gutierrez
źródło
2
Ta odpowiedź jest najlepsza! Dlaczego wszyscy mówią screen, zadawano pytanie po zalogowaniu, jak utrzymać procesy uruchomione, teraz po zalogowaniu, ale przed ich uruchomieniem. Świetna odpowiedź Jorge, naprawdę mi pomogłeś! :)
jwbensley,
1
Po prostu bg(bez %1) często wystarcza, ponieważ domyślną jest bieżąca praca
Walter Tross
Byłoby miło mieć kompleksową odpowiedź: A priori (konfiguracja z wyprzedzeniem): ekran terminalu ascii (stary), tmux (nowy); X windows: vnc (stary, nadal utrzymywany), xpra (nowszy), przy czym xpra jest pozbawiony root. A posterior (uporczywy po twoim rozpoczęciu): ^ Z, wyrzeknij się, ... Ale jestem zbyt leniwy, żeby to zrobić.
Krazy Glew
8

W przypadku pojedynczego skryptu powłoki, który mam uruchomiony przez długi czas, zaloguję się i uruchomię proces w tle za pomocą „&”.

Przykład:

/path/to/my/script &

Wylogowałem się i rozłączyłem sesję SSH. Kiedy loguję się jakiś czas później, skrypt nadal działa, co potwierdza ciągłe zbieranie danych ze skryptu.


źródło
3
Tak, chciałbym wiedzieć, w jaki sposób screen / tmux jest lepszy niż to proste rozwiązanie.
Mads Skjern
Tak, widzę to również na moim ubuntu, ale nie powinno tak się stać w teorii. Nie rozumiem dlaczego
Daniel Pinyol
1
@MadsSkjern Ponieważ nie można wprowadzić żadnych danych wejściowych do skryptu za pomocą tej metody.
Ken Sharp
1
@MadsSkjern powodem jest to, że jeśli uruchamiasz takie procesy za pomocą &wylogowania i zalogowania się do sesji SSH, proces będzie nadal działał, jednak nie będziesz w stanie zobaczyć wyniku tego procesu (jeśli twój skrypt powtórzył coś nie zobaczy go, ale jeśli zapisze plik, plik będzie tam)
DarkCygnus
4

Powinieneś sprawdzić ekran GNU i sprawdzić, czy ci to pomoże. W zależności od tego, jak chcesz, aby aplikacja działała w czasie rzeczywistym, może powodować więcej problemów niż rozwiązuje, ale przynajmniej pozwoli ci wznowić sesję tak, jakbyś jej nigdy nie opuszczał.

Jak używać :

  • Użyj polecenia screendo pierwszego uruchomienia, przewiń komunikaty wprowadzające, powinieneś otrzymać terminal.
  • Ca Cc otwiera kolejny terminal
  • Ca Ck zabija terminal
  • Za pomocą Ca C-Space i Ca C-Backspace można przełączać się między terminalami
  • Ca Ca jest przydatny, jeśli używasz tylko dwóch terminali
  • Ca Cd odłącza bieżącą sesję ekranu i wychodzi z ekranów. Następnie możesz użyć, screen -raby wznowić tę sesję. Możesz mieć kilka oddzielnych sesji ekranowych jednocześnie, w tym przypadku wyświetli się lista dostępnych sesji.

Istnieje wiele innych opcji, na przykład podzielone ekrany, a także wszystkie skróty można w pełni dostosować.

T. Verron
źródło
3

Najprostsza odpowiedź ...

ctrl + z zawiesi uruchomiony program

„bg” uruchomi go w tle

Roop
źródło
5
Bez odrzucenia procesu (za pomocą czegoś takiego jak disownlub nohup), zwykle nie spowoduje to kontynuacji procesu po zakończeniu sesji SSH.
Eliah Kagan,
3
Na moim serwerze Ubuntu, przy domyślnej konfiguracji, naprawdę działa!
Mads Skjern
3

Najprostszym sposobem jest uruchomienie polecenia w tle za pomocą &. Następnie po prostu napisz:

disown -a
Zibri
źródło
0

Podczas gdy wszyscy mówią, aby użyć disown(jedyna opcja, którą masz po rozpoczęciu procesu), nohuplub nawet uruchomienie polecenia screen, co jest przydatne, jeśli chcesz zobaczyć wszystkie dane wyjściowe polecenia ... Jestem fanem screen.. Nadal próbowałem najnowszych dystrybucji Linuksa w głównym nurcie i po prostu umieszczenie zadania w tle i zakończenie pracy nie powoduje śmierci wszystkich uruchomionych procesów. Musi istnieć globalne ustawienie lub coś takiego. Próbuję tego na niektórych dość starych systemach (slackware 12) i mój skrypt testowy działa, dopóki go ręcznie nie zabiję:

shell$ cat > test.pl

#!/usr/bin/perl
while(1){
     sleep(1);
}
    shell$ perl ./test.pl &
    shell$ exit
    logout
    shell$ ps aux test.pl
    mymom 31337     1  0 13:25 ?        00:00:00 perl ./test.pl
    shell$ 

Chociaż zgadzam się, że screenbyłby to najlepszy sposób na uruchomienie tego, nawet jeśli mój skrypt napisał do plików dziennika itp. Nigdy nie musiałem z niego korzystać disown -a lub nohupchyba, że ​​nie był to kompletna paranoja. Może ktoś może rzucić nieco światła na to, jak domyślnie zachowuje się bash? Może niektórzy administratorzy systemu zmieniają ustawienia domyślne dużych powłok, aby procesy użytkowników nie były przeciążone?

Dan Gullage
źródło
Jeśli masz dodatkowe pytania, zadaj je jako nowe pytanie
heemayl
0

Niestety zakończona sesja SSH może spowodować śmierć Tmux lub screena. Wynika to z faktu, systemdże wszelkie procesy potomne zostaną zakończone po wylogowaniu z sesji.

Możesz zmienić to ustawienie w swoim logind.conf( /etc/systemd/logind.conf):

KillUserProcesses=no

Dzięki odpowiedzi w https://unix.stackexchange.com/questions/490267 .

Jonathan
źródło
-1

Zamiast :

cmd options; 

Dodaj przed nohup:

nohup cmd options & 

Następnie zobaczysz standardowe wyjście konsoli:

tail -f nohup.out
Abdennour TOUMI
źródło