Utrzymywanie procesu linuksa uruchomionego po wylogowaniu

142

Łączę się z maszyną z systemem Linux za pośrednictwem SSH i próbuję uruchomić skrypt bash, który wykonuje operacje na systemie plików. Oczekuje się, że będzie działał przez wiele godzin, ale nie mogę pozostawić otwartej sesji SSH z powodu problemów z połączeniami internetowymi.

Wątpię, czy uruchomienie skryptu z operatorem w tle, ampersand ( &), załatwi sprawę, ponieważ próbowałem go, a później okazało się, że proces nie został zakończony. Jak mogę się wylogować i utrzymać ciągłość procesu?

doc_id
źródło

Odpowiedzi:

135

Najlepszą metodą jest rozpoczęcie procesu w terminalowym multiplekserze. Alternatywnie możesz sprawić, że proces nie odbierze sygnału HUP.


Zacisk multiplekser zapewnia „wirtualnych” terminale, które działają niezależnie od „prawdziwego” terminala (właściwie wszystkie terminale są dziś „wirtualne”, ale to inny temat na inny dzień). Wirtualny terminal będzie działał, nawet jeśli twój prawdziwy terminal jest zamknięty sesją ssh.

Wszystkie procesy uruchomione z wirtualnego terminala będą działały z tym wirtualnym terminalem. Po ponownym połączeniu z serwerem możesz ponownie połączyć się z wirtualnym terminalem i wszystko będzie tak, jakby nic się nie wydarzyło, oprócz upływu czasu.

Dwa popularne multipleksery terminalowe to screen i tmux .

Ekran ma stromą krzywą uczenia się. Oto dobry samouczek ze schematami wyjaśniającymi koncepcję: http://www.ibm.com/developerworks/aix/library/au-gnu_screen/


Sygnał HUP (lub SIGHUP) jest wysyłany przez terminal do wszystkich jego procesów potomnych, gdy terminal jest zamknięty. Powszechnym działaniem po otrzymaniu SIGHUP jest zakończenie. Tak więc, gdy twoja sesja ssh zostanie rozłączona, wszystkie twoje procesy zakończą się. Aby tego uniknąć, możesz sprawić, że twoje procesy nie będą otrzymywać SIGHUP.

Dwie proste metody to nohupi disown.

Aby uzyskać więcej informacji o tym, jak nohupi jak disowndziała, przeczytaj to pytanie i odpowiedź: https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

Uwaga: chociaż procesy będą nadal działać, nie możesz już z nimi współdziałać, ponieważ nie są one już podłączone do żadnego terminala. Ta metoda jest przydatna głównie w przypadku długotrwałych procesów wsadowych, które po uruchomieniu nie wymagają już żadnych działań ze strony użytkownika.

lesmana
źródło
3
Podoba mi się ta odpowiedź, ponieważ zapewnia rozwiązanie zarówno w sytuacjach interaktywnych, jak i nieinteraktywnych. W przypadku interaktywnym screendaje o wiele więcej opcji, ale jeśli używasz, authorized_keysaby umożliwić ludziom zdalne uruchamianie skryptu za pomocą ssh, ta nohupopcja jest przyjemnym prostym sposobem na uruchomienie przez skrypt procesów trwających dłużej niż sshsesja, przy której je uruchomiono. .
Mark Booth
1
@rahmanisback - Pamiętaj, że możesz zmienić zaakceptowaną odpowiedź w dowolnym momencie. To, że do tej pory odpowiedź Erica była wybierana najwyżej, nie oznacza, że ​​jest to najlepsza odpowiedź dla ciebie, a nawet uczynienie jej zaakceptowaną odpowiedzią może zachęcić więcej osób do głosowania na nią jako dobrą odpowiedź.
Mark Booth
3
* kaszel * tmuxisbetter * kaszel *
crasic
3
tmux > screen. Spróbuj, nigdy nie wrócisz.
h0tw1r3
1
@TheLQ - byobu jest ekranem GNU. Nadal używasz screena, tylko z wysoce dostosowanym .screenrc.
EEAA
92

Można to zrobić na kilka sposobów, ale najbardziej przydatny jest ekran GNU .

Po włączeniu się uruchom screen. Spowoduje to uruchomienie kolejnej powłoki działającej na ekranie. Uruchom polecenie, a następnie wykonaj polecenie Ctrl- a d.

Spowoduje to „odłączenie” cię od sesji ekranowej. W tym momencie możesz się wylogować lub zrobić cokolwiek innego.

Jeśli chcesz ponownie połączyć się z sesją ekranową, po prostu uruchom screen -RDpolecenie powłoki (jako ten sam użytkownik, który utworzył sesję).

EEAA
źródło
6
Screen ma całą masę poleceń, zaczynając od Ctrl-a. Jeśli nauczysz się tylko jednego dodatkowego, zacznij od „Ctrl-a?”. Więc nie będziesz chciał uczyć się „Ctrl-a c” i „Ctrl-a n”
olafure,
@olafure +1, dzięki. Wygląda na to, że Screen będzie z mojego podstawowego zestawu narzędzi.
doc_id
tmux > screen. Spróbuj, nigdy nie wrócisz.
h0tw1r3
+1 dla tmux. Zrezygnowałem z ekranu 5 tygodni temu.
Bryan Hunt
73

W bashThe disownkluczowe doskonale nadaje się do tego. Najpierw uruchom proces w tle (użyj &lub ^Zwpisz bg):

$ wget --quiet http://server/some_big_file.zip &
[1] 1156

Po wpisaniu jobsmożesz zobaczyć, że proces jest nadal własnością powłoki:

$ jobs
[1]+  Running  wget

Jeśli wylogujesz się w tym momencie, zadanie w tle również zostanie zabite. Jednak jeśli uruchomisz disown, bash odłączy zadanie i pozwoli mu kontynuować:

$ disown

Możesz to potwierdzić:

$ jobs
$ logout

Możesz nawet łączyć &i disownna tej samej linii, na przykład:

$ wget --quiet http://server/some_big_file.zip & disown
$ logout

nohupMoim zdaniem jest to lepsze niż uruchamianie, ponieważ nie pozostawia nohup.outplików zaśmieconych w całym systemie plików. Ponadto nohupnależy go uruchomić przed uruchomieniem polecenia - disownmożna go użyć, jeśli później zdecydujesz, że chcesz ustawić tło w tle i odłączyć zadanie.

Jeremy Visser
źródło
1
To bardzo dobra odpowiedź, 1+. Jedyną preferencją dla nohup lub Screen byłaby niezależność bash i może być używana z inną powłoką. Ale będę trzymać się twojego podejścia za każdym razem, gdy używam bash.
doc_id
Tak - jest to specyficzne dla bash, ponieważ bash jest jedyną powłoką, jakiej kiedykolwiek użyłem. Zastanawiam się, czy inne powłoki obsługują coś podobnego (tj. Uruchamianie w tle bez nohup) - byłoby fantastycznie, gdyby ktoś mógł opublikować inne odpowiedzi dla innych powłok.
Jeremy Visser,
1
patrz moja odpowiedź pokazująca, jak to zrobić za pomocą dowolnego sh-lookalike
w00t
1
+1 ze względu na możliwość późniejszego podjęcia decyzji. Właśnie w tym momencie miałem taką potrzebę. działał zgodnie z reklamą
code_monk
37

To zrobi narzędzie nohup, dostępne w większości Linuksów.

Korjavin Ivan
źródło
1
To zdecydowanie najprostsza odpowiedź. Każde wyjście z jest automatycznie kierowane do nohup.out i można je później sprawdzić.
Julian
3
nohup wcale nie wymaga zsh.
Aaron Brown,
nohup jest poprawną odpowiedzią, w skrócie oznacza brak zawieszenia.
Kinjal Dixit,
2
nohup znajduje się na znacznie większej liczbie komputerów niż screen, więc powinieneś wiedzieć, jak z niego korzystać.
Zenon
27

Żeby być dokładnym, zwrócę uwagę na tmux , który ma taki sam podstawowy pomysł jak screen:

tmux ma być nowoczesną, licencjonowaną przez BSD alternatywą dla programów takich jak ekran GNU. Główne cechy to:

  • Potężny, spójny, dobrze udokumentowany i łatwo skryptowalny interfejs poleceń.
  • Okno można podzielić poziomo i pionowo na szyby.
  • Panele można dowolnie przenosić i zmieniać ich rozmiar lub układać w gotowe układy.
  • Obsługa terminali UTF-8 i 256-kolorowych.
  • Skopiuj i wklej z wieloma buforami.
  • Interaktywne menu do wyboru okien, sesji lub klientów.
  • Zmień bieżące okno, wyszukując tekst w celu.
  • Blokowanie terminala, ręcznie lub po upływie limitu czasu.
  • Czysta, łatwa w rozbudowie baza kodów na licencji BSD, w trakcie aktywnego rozwoju.

Wyszukiwanie jest jednak w przybliżeniu nieskończenie łatwiejsze w Google.

Złota rączka 5
źródło
2
Używanie "gnu screen"jako zapytania wyszukiwania działa całkiem dobrze.
gnur
4
+1000 dla tmux!
mbq
11

Screen to przesada, aby procesy działały podczas wylogowania.

Spróbuj dtach :

dtach to program napisany w C, który emuluje funkcję odłączania ekranu, która pozwala na uruchomienie programu w środowisku chronionym przed terminalem sterującym. Na przykład program pod kontrolą dtach nie miałby wpływu na odłączenie terminala z jakiegoś powodu.

dtach został napisany, ponieważ screen nie spełniał moich potrzeb; Nie potrzebowałem dodatkowych funkcji ekranu, takich jak obsługa wielu terminali lub obsługa emulacji terminali. ekran był również zbyt duży, nieporęczny i miał trudny do zrozumienia kod źródłowy.

screen zakłócił także korzystanie z aplikacji pełnoekranowych, takich jak emacs i ircII, ze względu na nadmierną interpretację strumienia między programem a podłączonymi terminalami. dtach nie ma warstwy emulacji terminala i przekazuje nieprzetworzony strumień wyjściowy programu do dołączonych terminali. Jedyne przetwarzanie wejściowe, które wykonuje dtach, to skanowanie w poszukiwaniu znaku odłączenia (który sygnalizuje dtachowi odłączenie się od programu) i przetwarzanie klucza wstrzymania (który mówi dtachowi, aby tymczasowo zawiesił się bez wpływu na działający program), i oba z nich mogą oba w razie potrzeby można je wyłączyć.

W przeciwieństwie do screena, dtach ma minimalne funkcje i jest bardzo mały. Dzięki temu dtach może być łatwiej kontrolowany pod kątem błędów i dziur bezpieczeństwa, a także jest dostępny w środowiskach, w których jest mało miejsca, na przykład na dyskach ratunkowych.

sml
źródło
Dziękuję Ci. Przyszedłem tu tylko po to, żeby napisać o dtach. Teraz moim zadaniem jest oderwanie terminalu; ekran robi zbyt wiele i w niedorzeczny sposób zakłóca wprowadzanie danych. Fakt, że ekran wymaga własnego termcapu, jest dość niepokojący.
puszysty
9

Oto sposób na demonizację dowolnego procesu powłoki, bez potrzeby używania zewnętrznych programów:

( while sleep 5; do date; done ) <&- >output.txt &

Po zamknięciu sesji zadanie będzie nadal działać, o czym świadczy plik output.txt (który ma buforowanie, więc wyświetlenie wartości niezerowej zajmuje trochę czasu). Nie zapomnij zabić swojej pracy po testach.

Więc wszystko, co musisz zrobić, to blisko stdin i tło pracy. Aby być naprawdę dobrym, po pierwsze cd /, abyś nie trzymał się wierzchowca.

Działa to nawet w prostym sh w systemie Solaris.

w00t
źródło
Ciekawy. Pojawiły się pewne ważne pytania. Widzę, że ustawiłeś STDIN na nic, -operator? Jaka jest różnica między < /dev/nulli &-? Myślę, że STDIN (i innym STDOUT i STDERR) można przypisać albo plik < file, albo strumień przez <& streamw przypadku STDIN. Czy tak samo byłoby < /dev/nullw powyższym przykładzie? I czy -powyższy operator odnosi się do wartości null jako strumienia?
doc_id
Kiedy wykonasz x <& -, to zamyka deskryptor pliku x. W tym przypadku nie ma x, co powoduje, że bash jest domyślnie ustawiony na 1, tj. Standardowe wejście. Jeśli użyjesz </ dev / null, nie zamykasz standardowego wejścia, po prostu podajesz pusty plik do programu jako dane wejściowe.
w00t,
1
I szczerze mówiąc, tak naprawdę nie wiem, dlaczego demonizuje to, co prowadzisz :-) Mimo to działa, używamy go w produkcji. Odkryłem to, bawiąc się w nadziei, że mogę zdemonizować proces w powłoce bez potrzeby niczego specjalnego - więc zacząłem od zamknięcia standardowego wejścia i to wystarczyło. Powinienem przeczytać kilka źródeł powłoki, ale zakładam, że jeśli zamkniesz standardowe wejście i podłożysz proces do tła, spowoduje to również odłączenie procesu.
w00t,
2
Myślę, że powód jest taki, że SIGHUP (rzeczywisty sygnał, który powoduje, że dziecko kończy pracę po śmierci powłoki) jest uruchamiany, gdy proces nadrzędny zamyka uchwyt stdin swojego dziecka. Jeśli jednak standardowe wejście zaczyna się od zera, a nie jest zamykane po fakcie, rodzic nie może uruchomić SIGHUP. Niezłe znalezisko - nigdy bym o tym nie pomyślał.
Jeremy Visser,
@JeremyVisser, który brzmi naprawdę realistycznie!
w00t
7

atPolecenie może być przydatne do tego rodzaju sytuacji. Na przykład wpisz:

at now

Następnie możesz wprowadzić polecenie lub serię poleceń, które zostaną uruchomione. Wyniki należy przesłać pocztą e-mail, jeśli wiadomość e-mail jest poprawnie skonfigurowana w urządzeniu.

Zamiast tego nowmożesz opcjonalnie określić czas z datą lub wyrażeniem czasu, takim jak now + 15 minutes. Zobacz man atpo więcej szczegółów.

rjmunro
źródło
7

byobuna Ubuntu to przyjemny front-end do ekranu. Naciśnięcie Ctrl- ?wyświetla listę wszystkich skrótów klawiaturowych. Dodaje pasek stanu, który może być przydatny do obserwowania obciążenia procesora, miejsca na dysku itp. Ogólnie zapewnia doświadczenie, które opisałbym jako połączenie VNC oparte na terminalu.

nohup pozwala na uruchomienie zadania w tle, którego dane wyjściowe są kierowane do pliku dziennika, który zawsze można przekierować do / dev / null, jeśli nie jest to wymagane.

John Beckett
źródło