Zapobiegaj zabijaniu aktualnie uruchomionego zadania Linux po wylogowaniu z SSH

18

Mam zadanie obliczeniowe działające przez kilka dni na serwerze Linux za pośrednictwem połączenia SSH. Nie ma go w tle, więc połączenie SSH jest objęte zadaniem.

Chcę zrestartować komputer lokalny (nie serwer), z którego otworzyłem sesję ssh, ale chcę, aby zadanie nadal działało. Czy to w ogóle możliwe?

Ali
źródło

Odpowiedzi:

22

Jeśli zadanie jest już uruchomiony, to zbyt późno *, aby rozważyć alternatywne rozwiązania, wkładka dodatkowa warstwa między sshsesji i powłoce uruchamiając komendę, jak screen, tmux, byobu, nohupi lubi.

Jeśli twoje wsparcie procesu, które ma być umieszczone w tle, a szczególnie nie zawiesza się, stdouti stderrjest niezapisalne / zamknięte, możesz umieścić je w tle przed wylogowaniem, ControlZa bgnastępnie odłączyć od powłoki z disownwbudowanym.

na przykład:

$ ssh localhost
You have new mail.
Last login: Fri Jun  6 11:26:56 2014

$ /bin/sleep 3600    


^Z[1] + Stopped                  /bin/sleep 3600
$ bg
[1] /bin/sleep 3600&
$ jobs
[1] +  Running                 /bin/sleep 3600
$ disown %1
$ exit
Connection to localhost closed.
$ ps -ef|grep sleep
jlliagre 12864     1  0 21:12 ?        00:00:00 /bin/sleep 3600
jlliagre 13056 12477  0 21:13 pts/18   00:00:00 grep sleep
$ 

*Jak zauważył Bob, istnieje kilka hackerskich sposobów na odtworzenie sesji tty pod Linuksem. repty, retty , injcode i neercs . Najbardziej zaawansowany wygląda na reptyr, ale możesz potrzebować uprawnień roota, aby umożliwić ptrace włamanie się do twojego procesu.

jlliagre
źródło
Użyłem Ctrl + Z, zadanie zatrzymało się i przeniosłem na tło, a następnie wykonałem disownpolecenie. Zwrócił: bash: ostrzeżenie: usunięcie zatrzymanego zadania 1 z grupą procesów 24876. Teraz moje zadanie jest wymienione, ps -allale wydaje się, że nie działa (zużycie procesora wynosi 0%)
Ali
Wygląda na to, że mój proces został zatrzymany. Wydaje mi się, że powinienem dostarczyć identyfikator procesu z disownpoleceniem
Ali,
@Ali Myślę, że zapomniałeś uruchomić polecenia bg, aby wznowić zawieszone zadanie.
Jason Zhu,
1
@JasonZhu Dzięki za wskazanie tego. Nie było jasne, czy bgpolecenie było wymagane w pierwszej części mojej odpowiedzi. Edytowane.
jlliagre
2
Jeśli zapomniałeś komendy bg i uruchomiłeś tylko komendę disown, powinieneś być w stanie uruchomić proces ponownie, przy kill -CONTczym robi to mniej więcej tyle samo, co bg.
kasperd
5

Jednym z rozwiązań jest użycie ekranu GNU . Możesz uruchomić screen, uruchomić polecenie, a następnie odłączyć C-a d. Później, aby połączyć się ponownie, zrób to screen -ri wrócisz do poprzedniej sesji.

Inne zalety ekranu to zarządzanie oknami (dzięki czemu możesz przełączać się na inne powłoki podczas działania polecenia, bez potrzeby nowego połączenia SSH) i pozwala on pozostać na pierwszym planie, zarówno w bieżącej sesji, jak i późniejszej.

Edycja: Jak zauważono w komentarzach, zadziała to tylko wtedy, gdy pamiętasz, aby rozpocząć screenprzed uruchomieniem polecenia. Jeśli polecenie jest już uruchomione, będziesz potrzebować rozwiązania @ jlliagre.

Scott Weldon
źródło
2
tmuxto inny taki program, screenktóry pozwala na zdalną sesję, która nie jest powiązana z bieżącym połączeniem SSH.
Darth Android
2
Twoje rozwiązanie jest świetne. Jednak nie do końca pasuje do mojego pytania - zapytałem o aktualnie uruchomiony proces, a nie o proces, który w przyszłości będzie można uruchomić screen.
Ali
Ah, dobrze. W takim przypadku myślę, że będziesz musiał użyć rozwiązania @ jlliagre. (O ile mi wiadomo, nie ma sposobu na połączenie już uruchomionego procesu z czymś takim jak screenlub tmux.)
Scott Weldon
1

Jednym ze „standardowych” sposobów, aby to zrobić, jest użycie nohupzawartej w nim komendy coreutils:

nohup COMMAND [ARGS] &

Ale polecenie przekieruje dane wyjściowe ( STDOUTi STDERRAFAIK) programu do pliku nohup.out, co czasami będzie denerwujące (jak generowanie dużego pliku dziennika), więc możesz chcieć dokonać własnego przekierowania lub przekierować go do / dev / null Jeśli chcesz.

wangguoqin1001
źródło
2
Przeczytaj ponownie. Proces już działa .
Wyścigi lekkości z Monicą
zawstydzony nie czytał uważnie. Przepraszam.
wangguoqin1001
Właściwie nohupmożna do tego użyć. Wystarczy zawiesić uruchomiony proces i wysłać go do tła ( Ctrl+ Zi uruchomić bg), a następnie możesz go wydać nohup %1.
Mike
0

Oprócz tego nohupmożesz uruchomić proces w tle za pomocą „&” i podpowłoki:

Dodaj komendę do znaku & i zawiń ją w nawiasach

$ (thecommand args &)

Powiedzmy, że twój proces zyskuje pid 1922:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11473  2643  0 15:07 pts/1    00:00:00 bash
usr      11922     1  0 15:11 pts/1    00:00:00 thecommand

Spójrz, że nie jest przyłączony do procesu powłoki 11473, który był jego pierwotnym rodzicem. Tak więc, jeśli wyjdziesz lub zabijesz bieżącą powłokę (11473), proces 11922 będzie działał dalej i zostanie on odłączony od pts.

Spróbuj opuścić powłokę i wprowadzić nową powłokę. Nawet jeśli ta powłoka jest połączona z tymi samymi punktami, możesz teraz zobaczyć proces bez pts:

$ ps -fp 11922
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11922     1  0 15:11 ?        00:00:00 thecommand

Nie wiem, jak to się nazywa i dokumentuje w Posix, ale używam tego od 1990 w bsh, ksh, a teraz w bash.

Na koniec możesz użyć bgwbudowanego polecenia powłoki:

Po prostu uruchom program i jeśli zdecydujesz się go zatrzymać lub planujesz zachować go w tle, wpisz CTRL + Z:

$ thecommand
^Z
[1] Stopped          thecommand

Teraz pozwól mu dalej działać w tle:

$ bg
[1]+ thecommand &

Jeśli spojrzysz na informacje o procesie, ma on jeszcze proces nadrzędny:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12046  2643  0 15:18 pts/6    00:00:00 bash
usr      12571 12046  0 16:00 pts/6    00:00:00 thecommand
usr      12601 12046  0 16:04 pts/6    00:00:00 ps -f

Wyjdź z bieżącego procesu. Uruchomiony proces w tle jest odłączony od oryginalnego elementu nadrzędnego i działa w tle:

$ exit

Zaloguj się ponownie i spójrz na informacje o procesie:

$ ps -f 12571
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12571     1  0 16:00 ?        00:00:00 thecommand
Luciano
źródło