Dlaczego przeglądarka chromowa jest zabijana, kiedy zamykam terminal pomimo braku?


12

To pytanie jest stare i wciąż nie jestem pewien, dlaczego.


Pierwotne pytanie w 2014 r .:

Uruchomiłem zakładkę Gnome Terminal

$ nohup chromium-browser &

Ale kiedy zamykam kartę terminala, chromium-browserrównież wychodzi. Czy nie nohuppowinno temu zapobiec? Gilles powiedział:

Można powiedzieć, że nohup i disown oba tłumią SIGHUP, ale na różne sposoby. nohup powoduje, że program początkowo ignoruje sygnał (program może to zmienić). nohup stara się również zapewnić, że program nie będzie miał terminala sterującego, aby jądro nie wysyłało SIGHUP, gdy terminal jest zamknięty. disown jest czysto wewnętrzny względem powłoki; powoduje, że powłoka nie wysyła SIGHUP po zakończeniu.

Więc czy nohup nie powoduje, że przeglądarka chromowa ignoruje SIGHUP?

Widzę to również w innych plikach wykonywalnych, takich jak i Emacs (tryb GUI). Ale nie na Xeyes.

Dzieje się tak na Ubuntu 12.04, 32-bit, kiedy pytanie zostało opublikowane.


Aktualizacja w 2015 r.,

Teraz korzystam z Ubuntu 14.04, google-chromezamiast chromium-browserzainstalowanego. To samo, co stało się wcześniej z przeglądarką chromu, dzieje się teraz także z Google-Chrome. nohup google-chrome 2>/dev/null &nie zapisuje go przed zamknięciem, gdy karta terminala jest zamknięta. /usr/bin/google-chrometo link do skryptu bash /opt/google/chrome/google-chrome. Dlaczego nohupzastosowane do skryptu bash nie działa? Jak możemy sprawić, by działał na skryptach bash? Co ze skryptami Python?


1
Powinieneś powiedzieć więcej o swoim środowisku. Nie odtwarzam twojego przypadku testowego.
jlliagre

Z jakimi innymi plikami wykonywalnymi to widzisz? Wypróbuj coś prostego, na przykład xeyes.
Warren Young,

@WarrenYoung: Emacs (GUI). Ale xeyes działa.
Tim

Odpowiedzi:


12

Po zamknięciu okna terminala GNOME SIGHUP jest wysyłany do powłoki, w której był uruchomiony. Powłoka zwykle wysyła SIGHUP do każdej utworzonej grupy procesów - nawet tych, które rozpoczęły nohup- a następnie kończy działanie. Jeśli powłoka jest bash, pominie wysyłanie SIGHUP do dowolnej grupy procesów oznaczonej przez użytkownika disown.

Uruchomienie polecenia nohuppowoduje, że ignoruje SIGHUP, ale proces może to zmienić. Jeśli domyślnym ustawieniem jest SIGHUP dla procesu, to jeśli otrzyma SIGHUP, proces zostanie zakończony.

Linux zapewnia narzędzia do sprawdzania ustawień sygnału uruchomionego procesu.

Skrypt powłoki przeglądarki chromium wykonuje execskompilowaną aplikację, więc jej identyfikator procesu pozostaje taki sam. Aby zobaczyć ustawienia sygnału, pobiegłem, nohup chromium-browser &a potem spojrzałem, /proc/$!/statusaby zobaczyć dyspozycję sygnału.

SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180014003

To są liczby szesnastkowe. To pokazuje, że SIGHUP nie jest wyłapywany i nie jest ignorowany. Tylko SIGPIPE (13 bit w SigIgn) jest ignorowany. Prześledziłem to do następującego kodu :

// Setup signal-handling state: resanitize most signals, ignore SIGPIPE.
void SetupSignalHandlers() {
  // Sanitise our signal handling state. Signals that were ignored by our
  // parent will also be ignored by us. We also inherit our parent's sigmask.
  sigset_t empty_signal_set;
  CHECK(0 == sigemptyset(&empty_signal_set));
  CHECK(0 == sigprocmask(SIG_SETMASK, &empty_signal_set, NULL));

  struct sigaction sigact;
  memset(&sigact, 0, sizeof(sigact));
  sigact.sa_handler = SIG_DFL;
  static const int signals_to_reset[] =
      {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV,
       SIGALRM, SIGTERM, SIGCHLD, SIGBUS, SIGTRAP};  // SIGPIPE is set below.
  for (unsigned i = 0; i < arraysize(signals_to_reset); i++) {
    CHECK(0 == sigaction(signals_to_reset[i], &sigact, NULL));
  }

  // Always ignore SIGPIPE.  We check the return value of write().
  CHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR);
}

Mimo komentarza sygnały ignorowane przez rodzica nie są ignorowane. SIGHUP zabije chrom.

Obejściem tego problemu jest zrobienie tego, na co wskazuje @ xx4h: użyj disownpolecenia w bashu, aby jeśli bash musiał wyjść, nie wysyła SIGHUP do chromium-browsergrupy procesów. Możesz napisać funkcję, aby to zrobić:

mychromium () { /usr/bin/chromium-browser & disown $!; }

Dzięki. Teraz rozumiem głównie, co miałeś na myśli. „Ponieważ skrypt nigdy nie resetuje tej pułapki, rzeczywisty plik binarny chromu jest wywoływany z ustawieniem domyślnym dla SIGHUP”. Czy przez „zresetuj tę pułapkę” masz na myśli zmianę pułapki dla SIGHUP z powrotem na domyślną, co kończy proces? Jak „zresetować tę pułapkę”?
Tim

Och, przez „zresetuj tę pułapkę” miałem na myśli „przywrócić ustawienie tego sygnału z powrotem do stanu sprzed skryptu powłoki, który ustawił dla niego procedurę obsługi”. Jeśli powłoka tak zrobi trap "" 1, spowoduje to, że powłoka (i jej dzieci) zignorują SIGHUP. Wyjaśnię to.
Mark Plotnick

Dzięki. Sprawdzę to po wyjaśnieniu. Próbuję teraz zrozumieć demona, nohupa, disowna i pochodzenie, więc wróciłem, by wrócić do moich starych pytań i odpowiedzi, których nie rozumiałem. Pomyłki na temat nohup, disown i tła zostały w większości rozwiązane, a ja utknąłem w koncepcji demona i jak demonizować proces (patrz poniżej). Doceniam jeszcze raz, jeśli masz czas na pomoc.
Tim


Spojrzałem na chromowany kod aplikacji i okazuje się, że kod C ++ w aplikacji bezwarunkowo resetuje SIGHUP do domyślnego. Do trappolecenia w skrypcie otoki nie zapobiec, a bieg nohupnie może temu zapobiec. Poprawię moją odpowiedź, aby to odzwierciedlić.
Mark Plotnick

3

Jeśli chromium-browsercoś takiego, google-chrometo myślę, że najbardziej prawdopodobnym problemem jest to, że chromium-browser niechromium jest, ale jest to opakowanie powłoki, które inicjuje stan, a następnie execs chromium.

W mojej google-chromeinstalacji plik binarny znajduje się w rzeczywistości, /opt/google/chromea opakowanie /usr/binjest tylko skryptem powłoki, który konfiguruje wiele środowisk dotyczących xdg-*domyślnych i bezwzględnych ścieżek itp. Przed zamianą na binarny właściwy.

W tym momencie wszelkie sygnały, które nohuppoczątkowo mogły zostać zignorowane w imieniu skryptu, który wywołał jako swoje dziecko, przestaną mieć znaczenie i dopóki skrypt opakowania nie będzie ostrożny, aby ustawić go inaczej (co nie jest), molo zostanie odziedziczone.

Spróbuj file /usr/bin/chromium-browsersprawdzić, czy to jest skrypt powłoki. Jeśli tak, rozważ przepisanie go, aby lepiej Ci odpowiadało.

Mogę powiedzieć, że samo robienie tego google-chrome 2>/dev/null &sprawia, że ​​jest dla mnie otwarte, ale nie mogę sobie przypomnieć, czy jest to prawdopodobnie wynik modyfikacji, które wprowadziłem w skrypcie - to było ponad rok temu.


Dzięki. To samo, co zdarzyło się chromium-browserwcześniej, dzieje się także google-chrometeraz. Nie chromium-browserzainstalowałem nohup google-chrome 2>/dev/null &nie zapisuje go przed zamknięciem, gdy karta terminala jest zamknięta. google-chrometo skrypt bashowy /opt/google/chrome/google-chrome. Dlaczego nohup zastosowany do skryptu bash nie działa? Jak możemy sprawić, by działał na skryptach bash? Co ze skryptami Python?
Tim

Dobrze, to robi pracę nad scenariuszem, ale skrypt działa tylko przez kilka nanosekund przed zastąpiony przez rzeczywistą chromebinarny.
mikeserv

czy mówisz w skrypcie, że jest execw rzeczywistości chromeplik binarny? Jak zatem zmodyfikować skrypt? Oto mój/opt/google/chrome/google-chrome
Tim

@Tim - tak - patrz na dole? exec -a "$0" "$HERE/chrome" ... || exec -a "$0" "$HERE/chrome"... Na górze $HEREjest ustawiona wartość readlink $0 (dla której jest twoja ścieżka instalacji google-chrome), ale /opt/google/chrome/chromejest to plik binarny - tym właśnie skrypt zastępuje się.
mikeserv

@Tim: O ile to możliwe - możesz po prostu upuścić execprawdopodobnie. Skończysz z dodatkowym pidem (ponad 1000 innych) i procesem oczekiwania, ale myślę, że to jest jego zasięg. Albo możesz wymienić execw / nohupmoże. Wszystko zależy głównie od tego chrome, co będzie tolerować - ale tak powinno działać.
mikeserv

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.