Tại sao trình duyệt crom bị giết khi tôi đóng thiết bị đầu cuối mặc dù không có tiếng ồn?


12

Câu hỏi này đã cũ, và tôi vẫn chưa rõ tại sao.


Câu hỏi gốc năm 2014:

Trong tab Gnome Terminal, tôi đã chạy

$ nohup chromium-browser &

Nhưng khi tôi đóng tab thiết bị đầu cuối, chromium-browsercũng thoát. Không phải nohuplà để ngăn chặn điều đó? Gilles nói:

nohup và disown cả hai có thể được nói để đàn áp SIGHUP, nhưng theo những cách khác nhau. nohup làm cho chương trình bỏ qua tín hiệu ban đầu (chương trình có thể thay đổi điều này). nohup cũng cố gắng sắp xếp để chương trình không có thiết bị đầu cuối điều khiển, để nó sẽ không được gửi SIGHUP bởi kernel khi thiết bị đầu cuối bị đóng. disown hoàn toàn là nội bộ cho vỏ; nó khiến shell không gửi SIGHUP khi nó kết thúc.

Vì vậy, không nohup làm cho trình duyệt crom bỏ qua SIGHUP?

Tôi cũng thấy điều này trên các tệp thực thi khác, chẳng hạn như và Emacs (chế độ GUI). Nhưng không phải trên xeyes.

Điều này đang xảy ra trên Ubuntu 12.04, 32-bit khi câu hỏi được đăng.


Cập nhật năm 2015,

Bây giờ tôi đang chạy Ubuntu 14.04, google-chromethay vì chromium-browsercài đặt. Điều tương tự đã xảy ra với trình duyệt crom trước đây cũng xảy ra với google-chrome. nohup google-chrome 2>/dev/null &không lưu nó khỏi bị đóng khi tab terminal bị đóng. /usr/bin/google-chromelà một liên kết đến một tập lệnh bash /opt/google/chrome/google-chrome. Tại sao nohupáp dụng cho tập lệnh bash không hoạt động? Làm thế nào chúng ta có thể làm cho nó hoạt động trên các tập lệnh bash? Còn các kịch bản Python thì sao?


1
Bạn nên nói thêm về môi trường của bạn. Tôi không tái tạo trường hợp thử nghiệm của bạn.
jlliagre

Những thực thi khác mà bạn đang thấy điều này với? Hãy thử một cái gì đó đơn giản, ví dụ, như xeyes.
Warren Young

@WarrenYoung: Emacs (GUI). Nhưng xeyes hoạt động.
Tim

Câu trả lời:


11

Khi bạn đóng cửa sổ Gnome Terminal, SIGHUP được gửi đến trình bao mà nó đang chạy. Shell thường sẽ gửi SIGHUP tới mọi nhóm quy trình mà nó biết nó đã tạo - ngay cả những nhóm bắt đầu bằng nohup- và sau đó thoát. Nếu shell là bash, nó sẽ bỏ qua việc gửi SIGHUP tới bất kỳ nhóm quy trình nào mà người dùng đã đánh dấu disown.

Chạy một lệnh với nohupnó làm cho nó bỏ qua SIGHUP, nhưng quá trình có thể thay đổi điều đó. Khi bố trí SIGHUP cho một quy trình là mặc định, thì nếu nó nhận được SIGHUP, quy trình sẽ bị chấm dứt.

Linux cung cấp một số công cụ để kiểm tra cài đặt tín hiệu của quy trình đang chạy.

Tập lệnh shell trình duyệt crom thực hiện một execứng dụng được biên dịch, vì vậy ID tiến trình của nó vẫn giữ nguyên. Vì vậy, để xem các cài đặt tín hiệu của nó, tôi chạy nohup chromium-browser &và sau đó nhìn vào /proc/$!/statusđể xem cách xử lý tín hiệu.

SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180014003

Đó là những số hex. Điều này cho thấy SIGHUP không bị bắt và không bị bỏ qua. Chỉ SIGPIPE (bit thứ 13 trong SigIgn) bị bỏ qua. Tôi bắt nguồn từ này như sau đang :

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

Mặc dù bình luận, các tín hiệu bị phụ huynh bỏ qua không được bỏ qua. Một SIGHUP sẽ giết chết crôm.

Cách giải quyết là thực hiện những gì @ xx4h chỉ ra: sử dụng disownlệnh trong bash của bạn để nếu bash phải thoát, nó không gửi SIGHUP cho chromium-browsernhóm quy trình. Bạn có thể viết một hàm để làm điều này:

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

Cảm ơn. Bây giờ tôi đến để hiểu hầu hết những gì bạn có ý nghĩa. "Vì tập lệnh không bao giờ thiết lập lại bẫy này, nhị phân crom thực tế được gọi với bố trí của SIGHUP được đặt thành mặc định." Bằng cách "đặt lại bẫy này", bạn có nghĩa là thay đổi bẫy cho SIGHUP trở lại mặc định, điều này chấm dứt quá trình? Làm thế nào để bạn "thiết lập lại cái bẫy này"?
Tim

Ồ, bằng cách "thiết lập lại cái bẫy này", tôi có nghĩa là "đặt cách xử lý tín hiệu này trở lại như trước khi tập lệnh shell thiết lập một trình xử lý cho nó". Nếu cái vỏ đã làm trap "" 1, điều đó sẽ làm cho cái vỏ (và con của nó) bỏ qua SIGHUP. Tôi sẽ làm rõ điều này.
Đánh dấu Plotnick

Cảm ơn. Sẽ kiểm tra nó sau khi bạn làm rõ. Bây giờ tôi đang cố gắng để hiểu daemon, nohup, disown và nền, vì vậy tôi đã quay lại để xem lại những câu hỏi và câu trả lời cũ mà tôi không hiểu. Những nhầm lẫn về nohup, disown và nền chủ yếu được giải quyết, và tôi bị mắc kẹt với khái niệm daemon và làm thế nào để daemon hóa một quá trình (xem bên dưới). Tôi đánh giá cao một lần nữa nếu bạn có thời gian để giúp đỡ một lần nữa.
Tim


Tôi đã xem mã ứng dụng crom và hóa ra mã C ++ trong ứng dụng đặt lại SIGHUP về mặc định vô điều kiện. Các traplệnh trong trình bao bọc kịch bản lệnh shell không ngăn chặn điều này và việc chạy nohupkhông thể ngăn chặn điều này. Tôi sẽ xem lại câu trả lời của mình để phản ánh điều này.
Đánh dấu Plotnick

3

Nếu chromium-browsercó bất cứ điều gì giống như vậy google-chromethì tôi nghĩ vấn đề rất có chromium-browser thể không phảichromium là mà thay vào đó là một trình bao bọc để khởi tạo trạng thái sau đó execs chromium.

Trong phần google-chromecài đặt của tôi , tệp nhị phân thực sự nằm trong /opt/google/chromevà trình bao bọc /usr/binchỉ là một tập lệnh shell thiết lập rất nhiều môi trường liên quan đến xdg-*mặc định và các đường dẫn tuyệt đối và tương tự trước khi thay thế nó bằng nhị phân thích hợp.

Tại thời điểm này, bất kỳ tín hiệu nào nohupban đầu có thể bỏ qua thay mặt cho tập lệnh mà nó được gọi là con của nó sẽ không còn quan trọng và trừ khi tập lệnh bao bọc cẩn thận sắp xếp nó theo cách khác (không phải) , ctty được kế thừa.

Hãy thử file /usr/bin/chromium-browserkiểm tra xem nó có phải là shell-script không. Nếu vậy, hãy xem xét viết lại nó để phù hợp hơn với bạn.

Tôi có thể nói rằng chỉ cần làm google-chrome 2>/dev/null &cho nó mở cho tôi, nhưng tôi không thể nhớ lại nếu đó có thể là kết quả của những sửa đổi tôi đã thực hiện đối với kịch bản - nó đã hơn một năm trước.


Cảm ơn. Điều tương tự đã xảy ra chromium-browsertrước đây cũng xảy ra cho đến google-chromebây giờ. Tôi chưa chromium-browsercài đặt. nohup google-chrome 2>/dev/null &không lưu nó khỏi bị đóng khi tab terminal bị đóng. google-chromelà một kịch bản bash /opt/google/chrome/google-chrome. Tại sao nohup áp dụng cho tập lệnh bash không hoạt động? Làm thế nào chúng ta có thể làm cho nó hoạt động trên các tập lệnh bash? Còn các kịch bản Python thì sao?
Tim

Vâng, nó không làm việc trên các kịch bản, nhưng kịch bản chỉ chạy trong vài nano giây trước khi được thay thế bằng thực tế chromenhị phân.
mikeerv

bạn đang nói trong kịch bản có exectrên chromenhị phân thực tế không? Làm thế nào để tôi sửa đổi các kịch bản sau đó? Đây là của tôi/opt/google/chrome/google-chrome
Tim

@Tim - yeah - thấy đáy không? exec -a "$0" "$HERE/chrome" ... || exec -a "$0" "$HERE/chrome"... Ở trên cùng $HEREđược đặt thành giá trị của readlink $0 (đó là đường dẫn cài đặt của bạn google-chrome) nhưng /opt/google/chrome/chromelà nhị phân - đó là những gì tập lệnh thay thế chính nó.
mikeerv

@Tim: Theo như cách đi - bạn có thể bỏ execcó lẽ. Bạn sẽ kết thúc với một pid thêm (vượt quá 1000 người khác) và một quy trình vỏ chờ, nhưng tôi nghĩ đó là mức độ của nó. Hoặc nếu không bạn có thể thay thế execw / nohupcó thể. Tất cả phụ thuộc chủ yếu vào những gì chromesẽ chịu đựng - nhưng nó sẽ hoạt động như vậy.
mikeerv

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.