ทำไม Chromium-browser ถึงตายเมื่อฉันปิดเครื่อง


12

คำถามนี้เก่าและฉันยังไม่ชัดเจนว่าทำไม


คำถามต้นฉบับในปี 2014:

ในแท็บเทอร์มินัล Gnome ฉันวิ่ง

$ nohup chromium-browser &

แต่เมื่อฉันปิดแท็บเทอร์มินัลchromium-browserก็ออกจาก ไม่nohupควรที่จะป้องกันสิ่งนั้น? Gillesกล่าวว่า:

nohup และการปฏิเสธทั้งคู่สามารถกล่าวได้ว่าจะระงับ SIGHUP แต่ในรูปแบบที่แตกต่างกัน nohup ทำให้โปรแกรมไม่สนใจสัญญาณในตอนแรก (โปรแกรมอาจเปลี่ยนแปลงสิ่งนี้) nohup ยังพยายามจัดเรียงโปรแกรมไม่ให้มีเทอร์มินัลการควบคุมเพื่อที่จะไม่ได้ส่ง SIGHUP โดยเคอร์เนลเมื่อปิดเทอร์มินัล การแยกเป็นส่วนภายในของเชลล์อย่างหมดจด มันทำให้เชลล์ไม่ส่ง SIGHUP เมื่อมันยกเลิก

ดังนั้นไม่มีใครทำโครเมียมเบราว์เซอร์ไม่สนใจ SIGHUP?

ฉันเห็นสิ่งนี้ในไฟล์โปรแกรมอื่นเช่นและ Emacs (โหมด GUI) แต่ไม่ได้อยู่ที่ xeyes

สิ่งนี้เกิดขึ้นกับ Ubuntu 12.04 ซึ่งเป็น 32 บิตเมื่อมีการโพสต์คำถาม


อัพเดทในปี 2558

ตอนนี้ฉันใช้ Ubuntu 14.04 google-chromeแทนที่จะchromium-browserติดตั้ง สิ่งเดียวกันที่เกิดขึ้นกับโครเมียมเบราว์เซอร์ก่อนหน้านี้ก็เกิดขึ้นกับ google-chrome ด้วยเช่นกัน nohup google-chrome 2>/dev/null &ไม่บันทึกจากการปิดเมื่อแท็บเทอร์มินัลถูกปิด คือการเชื่อมโยงไปยังสคริปต์ทุบตี/usr/bin/google-chrome /opt/google/chrome/google-chromeเหตุใดจึงnohupใช้กับสคริปต์ทุบตีไม่ทำงาน เราจะทำให้มันทำงานกับสคริปต์ทุบตีได้อย่างไร สคริปต์ Python เกี่ยวกับอะไร


1
คุณควรบอกเพิ่มเติมเกี่ยวกับสภาพแวดล้อมของคุณ ฉันไม่ทำซ้ำกรณีทดสอบของคุณ
jlliagre

คุณเห็นสิ่งใดที่โปรแกรมปฏิบัติการอื่นนี้ใช้ xeyesลองสิ่งที่ง่ายสำหรับตัวอย่างเช่น
Warren Young

@WarrenYoung: Emacs (GUI) แต่ xeyes ใช้งานได้
ทิม

คำตอบ:


12

เมื่อคุณปิดหน้าต่างเทอร์มินัล GNOME SIGHUP จะถูกส่งไปยังเชลล์ที่ทำงานอยู่ โดยทั่วไปเชลล์จะส่ง SIGHUP ไปยังกลุ่มกระบวนการทั้งหมดที่รู้ว่าสร้างขึ้นแม้กระทั่งที่เริ่มต้นด้วยnohup- แล้วออก ถ้าเปลือกเป็นbashมันจะข้ามส่ง SIGHUP ไปยังกลุ่มกระบวนการใด ๆ disownที่ผู้ใช้ที่มีเครื่องหมาย

การรันคำสั่งด้วยnohupทำให้ไม่สนใจ SIGHUP แต่กระบวนการสามารถเปลี่ยนแปลงได้ เมื่อการจัดการของ SIGHUP สำหรับกระบวนการเป็นค่าเริ่มต้นหากได้รับ SIGHUP กระบวนการจะถูกยกเลิก

Linux จัดเตรียมเครื่องมือบางอย่างเพื่อตรวจสอบการตั้งค่าสัญญาณของกระบวนการที่กำลังทำงานอยู่

สคริปต์เชลล์โครเมี่ยมเบราว์เซอร์ทำexecแอพที่รวบรวมดังนั้น ID กระบวนการจึงยังคงเหมือนเดิม ดังนั้นเพื่อดูการตั้งค่าสัญญาณของฉันฉันวิ่งnohup chromium-browser &แล้วมองไปที่/proc/$!/statusเพื่อดูการจัดการสัญญาณ

SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180014003

นั่นคือตัวเลขฐานสิบหก สิ่งนี้แสดงว่า SIGHUP ไม่ถูกตรวจจับและไม่ถูกเพิกเฉย SIGPIPE (บิตที่ 13 ใน SigIgn) เท่านั้นที่ถูกละเว้น ฉันติดตามสิ่งนี้ไปยังรหัสต่อไปนี้:

// 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 ชี้ให้เห็น: ใช้disownคำสั่งใน bash ของคุณเพื่อที่ถ้า bash ต้องออกก็ไม่ส่ง SIGHUP ไปยังchromium-browserกลุ่มกระบวนการ คุณสามารถเขียนฟังก์ชันเพื่อทำสิ่งนี้:

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

ขอบคุณ ตอนนี้ฉันมาทำความเข้าใจส่วนใหญ่ในสิ่งที่คุณหมายถึง "เนื่องจากสคริปต์ไม่ได้รีเซ็ตแทร็ปนี้เลย Chromium ไบนารีจริงจึงถูกเรียกด้วยการจัดการของ SIGHUP ที่ตั้งไว้เป็นค่าเริ่มต้น" โดย "รีเซ็ตแทร็บนี้" คุณหมายถึงการเปลี่ยนแทร็พสำหรับ SIGHUP กลับไปเป็นค่าเริ่มต้นซึ่งยุติกระบวนการหรือไม่ คุณจะ "รีเซ็ตกับดักนี้" ได้อย่างไร
ทิม

โอ้โดย "รีเซ็ตแทร็บนี้" ฉันหมายถึง "ตั้งค่าการจัดการของสัญญาณนี้กลับไปสู่แบบที่มันเป็นก่อนที่สคริปต์เชลล์จะตั้งค่าตัวจัดการ" หากเชลล์ทำtrap "" 1สิ่งนั้นจะทำให้เชลล์ (และลูก ๆ ) นั้นละเว้น SIGHUP ฉันจะชี้แจงเรื่องนี้
Mark Plotnick

ขอบคุณ จะตรวจสอบหลังจากการชี้แจงของคุณ ตอนนี้ฉันกำลังพยายามเข้าใจ daemon, nohup, disown และ background ดังนั้นฉันกลับมาอีกครั้งเพื่อตอบคำถามเก่าและคำตอบที่ฉันไม่เข้าใจ ความสับสนเกี่ยวกับ nohup, การปฏิเสธและพื้นหลังส่วนใหญ่ได้รับการแก้ไขและฉันติดอยู่กับแนวคิดของภูตและวิธีการ daemonize กระบวนการ (ดูด้านล่าง) ฉันขอขอบคุณอีกครั้งหากคุณมีเวลาช่วยเหลืออีกครั้ง
ทิม


ฉันดูที่รหัสแอป Chromium และปรากฎรหัส C ++ ในแอปพลิเคชันรีเซ็ต SIGHUP เป็นค่าเริ่มต้นโดยไม่มีเงื่อนไข trapคำสั่งในสคริปต์เปลือกห่อหุ้มไม่ป้องกันการนี้และทำงานnohupไม่สามารถป้องกันปัญหานี้ ฉันจะแก้ไขคำตอบเพื่อสะท้อนสิ่งนี้
Mark Plotnick

3

หากchromium-browserเป็นสิ่งที่ชอบgoogle-chromeแล้วฉันคิดว่าปัญหาส่วนใหญ่คือchromium-browser ไม่ได้chromiumแต่แทนที่จะเป็นเปลือกห่อหุ้มซึ่งเริ่มต้นแล้วรัฐsexecchromium

ในgoogle-chromeการติดตั้งของฉันไบนารีตั้งอยู่ในจริง/opt/google/chromeและ wrapper ใน/usr/binเป็นเพียงเชลล์สคริปต์ที่ตั้งค่าจำนวนมากของสภาพแวดล้อมที่เกี่ยวข้องกับxdg-*ค่าเริ่มต้นและเส้นทางที่แน่นอนและที่คล้ายกันก่อนที่จะแทนที่ตัวเองด้วยไบนารีที่เหมาะสม

ณ จุดนี้สัญญาณใด ๆ ที่nohupอาจถูกละเว้นในขั้นต้นในนามของสคริปต์ที่เรียกว่าเป็นลูกของมันจะหยุดเรื่องและถ้าสคริปต์ wrapper ระมัดระวังในการจัดเรียงเป็นอย่างอื่น(ซึ่งไม่ใช่) ctty จะถูกสืบทอด

ลองfile /usr/bin/chromium-browserตรวจสอบว่ามันเป็นเชลล์สคริปต์หรือไม่ หากเป็นเช่นนั้นให้ลองเขียนใหม่อีกครั้งเพื่อให้เหมาะกับคุณมากขึ้น

ฉันสามารถพูดได้ว่าเพียงแค่google-chrome 2>/dev/null &เปิดไว้สำหรับฉัน แต่ฉันจำไม่ได้ว่าเป็นผลมาจากการปรับเปลี่ยนที่ฉันทำกับสคริปต์ - เมื่อประมาณหนึ่งปีที่แล้ว


ขอบคุณ สิ่งเดียวกันที่เกิดขึ้นchromium-browserก่อนหน้านี้ก็เกิดขึ้นเช่นgoogle-chromeกัน ฉันไม่ได้chromium-browserติดตั้ง nohup google-chrome 2>/dev/null &ไม่บันทึกจากการปิดเมื่อแท็บเทอร์มินัลถูกปิด เป็นสคริปต์ทุบตีgoogle-chrome /opt/google/chrome/google-chromeทำไม nohup ถึงใช้กับ bash script ไม่ทำงาน? เราจะทำให้มันทำงานกับสคริปต์ทุบตีได้อย่างไร สคริปต์ Python เกี่ยวกับอะไร
ทิม

มันใช้งานได้กับสคริปต์ แต่สคริปต์จะทำงานเพียงไม่กี่วินาทีนาโนก่อนที่จะถูกแทนที่ด้วยchromeไบนารีจริง
mikeserv

คุณกำลังบอกว่าในสคริปต์มีอยู่execในchromeไบนารีจริง? ฉันจะแก้ไขสคริปต์ได้อย่างไร นี่คือของฉัน/opt/google/chrome/google-chrome
ทิม

@Tim - ใช่ - ดูที่ด้านล่าง? exec -a "$0" "$HERE/chrome" ... || exec -a "$0" "$HERE/chrome"... ที่ด้านบนสุด$HEREถูกตั้งค่าเป็นreadlink $0 (ซึ่งเป็นเส้นทางการติดตั้งของคุณgoogle-chrome)แต่/opt/google/chrome/chromeเป็นไบนารี - ซึ่งเป็นสิ่งที่สคริปต์แทนที่ตัวเองด้วย
mikeserv

@ Tim: เท่าที่วิธีการที่จะไป - คุณก็สามารถลดลงexecอาจจะ คุณจะปิดท้ายด้วย pid พิเศษ(เกิน 1,000 ตัว)และกระบวนการ shell ที่รอ แต่ฉันคิดว่านั่นคือขอบเขตของมัน มิฉะนั้นคุณอาจแทนที่execด้วยnohupบางที ทุกอย่างขึ้นอยู่กับสิ่งที่chromeจะทน - แต่มันควรจะทำงานเช่นนั้น
mikeserv

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.