nohup에도 불구하고 터미널을 닫으면 Chrome 브라우저가 종료되는 이유는 무엇입니까?

nohup에도 불구하고 터미널을 닫으면 Chrome 브라우저가 종료되는 이유는 무엇입니까?

이 질문은 꽤 오래되었으며 여전히 이유를 잘 모르겠습니다.


2014년의 원래 질문:

Gnome Terminal 탭에서 다음을 실행합니다.

$ nohup chromium-browser &

하지만 터미널 탭을 닫으면 chromium-browser종료됩니다. nohup멈춰야 하지 않겠습니까 ?자일스설명하다:

nohup과 disown은 모두 SIGHUP을 억제한다고 할 수 있지만 그 방식은 다릅니다. nohup은 프로그램이 처음에 신호를 무시하도록 합니다(프로그램이 이를 변경할 수 있음). nohup은 또한 터미널이 닫힐 때 커널이 SIGHUP 신호를 보내지 않도록 프로그램이 터미널을 제어하지 않도록 준비하려고 시도합니다. disown은 순전히 쉘 내부에 있으며 SIGHUP을 보내지 않고 쉘이 종료됩니다.

그렇다면 nohup은 크롬 브라우저가 SIGHUP을 무시하도록 만들지 않을까요?

나는 Emacs(GUI 모드)와 같은 다른 실행 파일에서 이것을 본 적이 있습니다. 하지만 xeyes에서는 그렇지 않습니다.

질문이 게시되었을 때 이는 32비트 Ubuntu 12.04에서 발생했습니다.


2015년에 업데이트되었으며,

google-chrome이제 설치하는 대신 Ubuntu 14.04를 실행하고 있습니다 chromium-browser. 크롬 브라우저에서 일어났던 것과 똑같은 일이 이제 구글 크롬에서도 일어나고 있습니다. nohup google-chrome 2>/dev/null &터미널 탭을 닫을 때 닫히는 것을 방지하지 않습니다. /usr/bin/google-chromebash 스크립트에 대한 링크입니다 /opt/google/chrome/google-chrome. nohupBash 스크립트에 적용하면 작동하지 않는 이유는 무엇입니까 ? Bash 스크립트에서 어떻게 작동하게 할 수 있나요? Python 스크립트는 어떻습니까?

답변1

GNOME 터미널 창을 닫으면 SIGHUP 신호가 실행 중인 셸로 전송됩니다. 쉘은 일반적으로 생성된 것으로 알고 있는 모든 프로세스 그룹(시작된 프로세스 그룹 포함 nohup)에 SIGHUP을 보낸 다음 종료합니다. 그렇다면 쉘은 bash사용자가 표시한 프로세스 그룹에 SIGHUP 전송을 건너뜁니다 disown.

명령을 실행하면 nohupSIGHUP이 무시되지만 프로세스에서 이를 변경할 수 있습니다. 프로세스의 SIGHUP 처리가 기본값인 경우 SIGHUP을 수신하면 프로세스가 종료됩니다.

Linux는 실행 중인 프로세스의 신호 설정을 검사하는 도구를 제공합니다.

크롬 브라우저 셸 스크립트는 exec컴파일된 애플리케이션에서 작동하므로 해당 프로세스 ID는 변경되지 않습니다. 그래서 신호 설정을 보기 위해 조금 실행하여 신호 구성을 nohup chromium-browser &살펴보았습니다 ./proc/$!/status

SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180014003

이는 16진수입니다. 이는 SIGHUP이 포착되지 않았거나 무시되었음을 나타냅니다. SIGPIPE(SigIgn의 비트 13)만 무시됩니다. 나는 다음을 추적했다암호:

// 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);
}

이런 말에도 불구하고 부모가 무시하는 징후는 다음과 같습니다.아니요무시되었습니다. SIGHUP은 크롬을 죽입니다.

해결책은 @xx4h가 지적한 대로 수행하는 것입니다. 즉, bash가 종료되어야 하는 경우 프로세스 그룹에 SIGHUP을 보내지 disown않도록 bash에서 명령을 사용하는 것입니다 . chromium-browser이를 수행하는 함수를 작성할 수 있습니다.

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

답변2

크롬이 특별해 보이네요.

nohup chromium-browser & disown이 경우 작동해야합니다. 또한보십시오: https://stackoverflow.com/questions/11421810/nohup-doesnt-work-with-chromium

답변3

그렇다면 가장 큰 문제는 다음과 같습니다 chromium-browser.google-chromechromium-browser 아니요chromiumexec그러나 이는 상태를 먼저 초기화한 다음 s 를 초기화하는 쉘 래퍼입니다 chromium.

google-chrome설치에는 바이너리가 실제로 그 안에 있으며 /opt/google/chrome내부 래퍼는 기본값 및 절대 경로 등에 대한 /usr/bin많은 환경을 설정한 xdg-*다음 이를 올바른 바이너리로 바꾸는 쉘 스크립트일 뿐입니다.

이 시점에서 nohup하위 첨자로 호출된 스크립트에 의해 처음에 무시되었을 수 있는 모든 신호는 래퍼 스크립트가 이를 주의 깊게 다르게 정렬하지 않는 한 더 이상 중요하지 않습니다.(그러나 실제로는 그렇지 않다)ctty는 상속됩니다.

file /usr/bin/chromium-browser내 생각에 쉘 스크립트인지 확인하려고 합니다 . 그렇다면 자신에게 더 적합하도록 다시 작성해 보세요.

이렇게 하는 것만으로도 마음이 열려 있었다고 말할 수 있지만 google-chrome 2>/dev/null &, 그것이 제가 스크립트를 변경한 결과였는지 기억이 나지 않습니다. 그것은 1년이 넘었습니다.

관련 정보