Jeśli uruchomię proces w tle, a następnie wyloguję się, czy będzie on nadal działał?

29

Pytając o to po długiej dyskusji ze współpracownikiem, naprawdę chciałbym tu wyjaśnić.

Uruchamiam proces w tle, dodając „ &” do wiersza poleceń lub zatrzymując go CTRL-Zi wznawiając go w tle za pomocą „ bg”. Następnie wylogowuję się.

Co się dzieje?

Byliśmy całkiem pewni, że to powinien był zostać zabity przez SIGHUP, ale tak się nie stało; po ponownym zalogowaniu proces przebiegał pomyślnie i pstreepokazał, że został „przyjęty” przez init.

Czy to jest oczekiwane zachowanie?

Ale jeśli tak, jaki nohupjest cel polecenia? Wygląda na to, że proces i tak nie zostanie zabity, z nim lub bez niego ...


Edytuj 1

Kilka dodatkowych szczegółów:

  • Polecenie zostało uruchomione z sesji SSH, a nie z fizycznej konsoli.
  • Komenda została uruchomiona bez nohup i / lub &; następnie został zawieszony CTRL-Zi wznowiony w tle z bg.
  • Sesja ssh nie spadła. Wystąpiło rzeczywiste wylogowanie ( exitpolecenie „ ”).
  • Proces był scpoperacją kopiowania plików.
  • Po ponownym zalogowaniu pstreepokazał , że proces działa i że jest dzieckiem init.

Edytuj 2

Uściślenie pytania: czy umieszczenie procesu w tle (za pomocą &lub bg) spowoduje, że będzie on ignorowany SIGHUP, tak jak nohuppolecenie?


Edytuj 3

Próbowałem ręcznie wysłać SIGHUPdo scp: wyszedł, więc zdecydowanie nie ignoruje sygnału.

Następnie spróbowałem ponownie uruchomić go, umieszczając go w tle i wylogowując się: został „adoptowany” przez initi działał dalej, i znalazłem go tam podczas ponownego logowania.

Jestem teraz dość zaskoczony. Wygląda na to, że w ogóle nie SIGHUPwysłano żadnego dodatkowego logowania.

Massimo
źródło
Nie widziałem tam żadnej wzmianki o I / O konsoli, która również potknie się. Czy przekierowałeś rzeczy np. 1>/dev/null 2>&1Na bash itp.?
Avery Payne
Nie, nie zrobiłem tego. SCP oczywiście nie wymagało standardowego wejścia ... i standardowe wyjście nie wydawało się być problemem.
Massimo
To, czy powłoka jest wykonywana jako powłoka logowania, zmienia wydajność, co może mieć miejsce w tym przypadku.
Warner
Zrobiłem kilka innych testów; Podsumowałem to tutaj: serverfault.com/questions/117152 .
Massimo

Odpowiedzi:

20

Odpowiedź znaleziona.

W przypadku BASH zależy to od huponexitopcji powłoki, którą można wyświetlić i / lub ustawić za pomocą wbudowanego shoptpolecenia.

Wygląda na to, że ta opcja jest domyślnie wyłączona, przynajmniej w systemach opartych na RedHat.

Więcej informacji na stronie podręcznika BASH :

Powłoka wychodzi domyślnie po otrzymaniu SIGHUP. Przed wyjściem interaktywna powłoka ponownie wysyła SIGHUP do wszystkich zadań, uruchomionych lub zatrzymanych. Zatrzymane zadania są wysyłane SIGCONT, aby upewnić się, że otrzymają SIGHUP. Aby zapobiec wysyłaniu przez powłokę sygnału do określonego zadania, należy ją usunąć z tabeli zadań z wbudowanym disown (patrz POLECENIA WBUDOWANE POWŁOKI poniżej) lub zaznaczyć, aby nie odbierać POWIĘKSZENIA za pomocą disown -h.

Jeśli opcja huponexit została ustawiona w shopt, bash wysyła SIGHUP do wszystkich zadań, gdy kończy się interaktywna powłoka logowania.

Massimo
źródło
2
To głupie domyślne, ale moje wnętrzności mówią mi, że to raczej błąd RH niż bash. Btw, z zsh możesz używać i! jako skrót do odrzucenia, a procesy rozwidlone za pomocą & do get sighup.
Jürgen Strobel,
7

Zgadzam się z Warnerem i chcę tylko dodać, że możesz powstrzymać powłokę przed wysyłaniem SIGHUP za pomocą wbudowanego polecenia „disown”. Strona podręcznika bash zawiera dobry opis.

Kim
źródło
4

Możesz użyć polecenia nohup, aby uruchomić polecenie i przekierować dane wyjściowe do pliku wyjściowego nohup. Ze strony podręcznika nohup:

nohup - run a command immune to hangups, with output to a non-tty

Inną opcją jest użycie polecenia screen . Zaletą korzystania z ekranu jest to, że możesz ponownie połączyć się z procesem później.

Jim
źródło
Dlaczego opinie negatywne? Korzystanie z nohup i screena jest całkowicie akceptowalnym sposobem na uniknięcie zabicia procesu podczas wylogowywania. Są inne, ale oba działają. O co chodzi?
Jim
2
Myślę, że to świetny punkt, ale pytanie dotyczy tego, dlaczego jego procesy nie są zabijane, a NIE „jak uchronić je przed zabiciem”.
CarpeNoctem
2

Gdy rozwidlisz proces w tle, nadal będzie to proces potomny wykonywanej przez powłokę.

Wszystkie procesy potomne działające w powłoce są wysyłane SIGHUP przy wyjściu. Wydajność różni się nieznacznie w zależności od dokładnej sytuacji, która jest szczegółowo opisana na stronie podręcznika bash. Inne pociski prawdopodobnie mają podobne opisy.

Apache i inne demony zwykle przeładowują konfigurację w SIGHUP. Narzędzia przestrzeni użytkownika często umierają. Wydajność aplikacji powiązana z sygnałami może być unikalna dla aplikacji.

Warner
źródło
W takim przypadku proces powinien otrzymać SIGHUP, prawda? Może to po prostu zignorowało, sprawdzę.
Massimo
Tak, dokładnie. Uważam, że taka właśnie jest sytuacja. Jeśli naprawdę wątpisz w udokumentowane działanie, możesz zhakować mały skrypt, aby przechwycić sygnał i zarejestrować go.
Warner
0

Jaki był proces? Wydajność opisana we wcześniejszym poście 1 była dokładna.

Niektóre funkcje i procesy skryptowe mogą przechwytywać sygnały. podczas gdy pętle mogą uciec jak szalone.

Widzieć:

Sesja SSH spada - czy polecenie jest nadal wykonywane?

Edytuj 1 o 16:22

Z strony podręcznika bash:

The shell exits by default upon receipt of a SIGHUP.   Before  exiting,
an  interactive  shell  resends  the  SIGHUP  to  all  jobs, running or
topped.

Wstępne badania 1 pokazują, że OpenSSH prawdopodobnie ignoruje SIGHUP, może więcej sygnałów.

Warner
źródło
Ten post naprawdę zmusił mnie do zadania pytania. Aby uzyskać szczegółowe informacje, patrz edycja powyżej.
Massimo
2
Odpowiedzi w drugim wątku brzmią tak, jakbyś musiał przeczytać o poleceniu SCP, którego używasz, i zobaczyć, jak reaguje na SIGHUP
mfinni
A „nohup” dotyczy poleceń, o których wiesz, że umrą z PODSUMOWANIEM i chyba nie chcesz ich.
mfinni
Strona podręcznika po prostu tego nie mówi; Spróbuję go zabić -HUP jutro ...
Massimo
-1

Jeśli nie uruchomiłeś polecenia za pomocą narzędzia takiego jak screen, to po zakończeniu sesji, podobnie jak wszystkie zadania / zadania związane z tą sesją.

królikarnia
źródło
Właśnie o tym myślałem, tyle że ... po prostu nie.
Massimo
mają za każdym razem, gdy robię to, co opisałeś ... może to zależy od używanej powłoki?
warren
-1 nie; odpowiedź nie jest taka prosta. Właśnie przetestowałem prosty skrypt powłoki, który uruchomiłem w tle; zapętlił i wysłał dane wyjściowe do pliku tymczasowego. Nadal działał po wyjściu z terminala (jak widać tail -fw pliku tymczasowym. To na komputerze CentOS 7.1 za pomocą bash.
Mike S
@MikeS - proszę wykazać. Nigdy nie byłem świadkiem opisywanego zachowania
warren
@warren - Zobacz moją odpowiedź na serverfault.com/questions/117152/… . Pamiętaj, że wiele osób twierdzi, że zachowuje się inaczej niż to, co opisujesz; rzeczywiście Massimo napisał właśnie dlatego, że jego proces trwał.
Mike S