ใครสามารถอธิบายรายละเอียดสิ่งที่ "set -m" ทำอะไรได้บ้าง


17

ในหน้า manมันแค่พูดว่า:

เปิดใช้งานการควบคุมงาน

แต่สิ่งนี้หมายความว่าอย่างไร

ฉันเจอคำสั่งนี้ด้วยคำถาม SOฉันมีปัญหาเดียวกันกับ OP ซึ่งเป็น "fabric ไม่สามารถเริ่ม tomcat" ได้ และset -mแก้ไขสิ่งนี้ OP อธิบายเล็กน้อย แต่ฉันไม่เข้าใจ:

ปัญหานี้อยู่ในงานพื้นหลังเนื่องจากจะถูกฆ่าเมื่อคำสั่งสิ้นสุดลง

วิธีแก้ปัญหานั้นง่าย: เพียงเพิ่ม "set -m;" คำนำหน้าก่อนคำสั่ง

คำตอบ:


10

การอ้างอิงเอกสารทุบตี (จากman bash):

JOB CONTROL
       Job  control  refers to  the  ability  to selectively  stop
       (suspend) the execution of  processes and continue (resume)
       their execution at a later point.  A user typically employs
       this facility via an interactive interface supplied jointly
       by the operating system kernel's terminal driver and bash.

ดังนั้นพูดง่ายๆว่าการมีset -m(ค่าเริ่มต้นสำหรับเชลล์แบบโต้ตอบ) อนุญาตให้ใช้บิวด์อินเช่นfgและbgซึ่งจะถูกปิดการใช้งานภายใต้set +m(ค่าเริ่มต้นสำหรับเชลล์ที่ไม่มีการโต้ตอบ)

ฉันไม่เห็นชัดเจนว่าการเชื่อมต่อระหว่างการควบคุมงานและการฆ่ากระบวนการพื้นหลังเมื่อออกคืออะไร แต่ฉันสามารถยืนยันได้ว่ามีอย่างใดอย่างหนึ่ง: การทำงานset -m; (sleep 10 ; touch control-on) &จะสร้างไฟล์ถ้าใครออกจากเชลล์ทันทีหลังจากพิมพ์คำสั่งนั้น แต่set +m; (sleep 10 ; touch control-off) &จะไม่

ฉันคิดว่าคำตอบนั้นอยู่ในเอกสารที่เหลือสำหรับset -m:

-m      Monitor  mode. [...]                     Background pro‐
        cesses run in a separate process group and a  line  con‐
        taining  their exit status is printed upon their comple‐
        tion.

ซึ่งหมายความว่างานพื้นหลังที่เริ่มต้นภายใต้set +mไม่ใช่ "กระบวนการพื้นหลัง" ที่แท้จริง ("กระบวนการพื้นหลังเป็นงานที่ ID กลุ่มกระบวนการแตกต่างจากเทอร์มินัล"): พวกเขาแบ่งปัน ID กลุ่มกระบวนการเดียวกันกับเชลล์ที่เริ่มทำงาน กลุ่มกระบวนการเช่นกระบวนการพื้นหลังที่เหมาะสม สิ่งนี้จะอธิบายพฤติกรรมที่สังเกตได้เมื่อเชลล์หยุดทำงานก่อนที่งานแบ็คกราวน์บางส่วน: ถ้าฉันเข้าใจถูกต้องเมื่อออกจากงานสัญญาณจะถูกส่งไปยังกระบวนการในกลุ่มกระบวนการเดียวกันกับเชลล์ (ดังนั้นจึงฆ่างานพื้นหลังที่เริ่มต้นset +m) ไปยังกลุ่มกระบวนการอื่น ๆ (ดังนั้นปล่อยให้กระบวนการพื้นหลังจริงเริ่มต้นภายใต้set -m)

ดังนั้นในกรณีของคุณstartup.shสคริปต์น่าจะเริ่มงานพื้นหลัง เมื่อสคริปต์นี้ทำงานแบบไม่มีการโต้ตอบเช่นผ่าน SSH ดังเช่นในคำถามที่คุณเชื่อมโยงการควบคุมงานถูกปิดใช้งานงาน "แบ็คกราวน์" จะแบ่งปันกลุ่มกระบวนการของรีโมตเชลล์และจะถูกฆ่าทันทีที่เชลล์ออกจาก ในทางกลับกันเมื่อเปิดใช้งานการควบคุมงานในเชลล์นั้นงานแบ็คกราวน์จะได้รับกลุ่มกระบวนการของตัวเองและจะไม่ถูกฆ่าเมื่อเชลล์พาเรนต์ออก


ขอบคุณสำหรับคำตอบของคุณ แต่มีความtomcat/bin/startup.shเกี่ยวข้องกับfg/ bgอย่างไร
laike9m

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

2

ฉันพบสิ่งนี้ในรายการปัญหา GitHub และฉันคิดว่านี่จะตอบคำถามของคุณได้จริงๆ

มันไม่ใช่ปัญหา SSH จริง ๆ มันเป็นพฤติกรรมที่ละเอียดกว่าโหมด BASH แบบไม่โต้ตอบ / โต้ตอบและการแพร่สัญญาณไปยังกลุ่มกระบวนการ

การติดตามจะขึ้นอยู่กับ /programming/14679178/why-does-ssh-wait-for-my-subshells-without-t-and-kill-them-with-t/14866774#14866774 และhttp: //www.itp.uzh.ch/~dpotter/howto/daemonizeด้วยสมมติฐานบางอย่างที่ไม่ผ่านการตรวจสอบอย่างสมบูรณ์ แต่ทดสอบว่างานนี้ดูเหมือนจะยืนยันได้อย่างไร

pty / tty = false

เปลือก bash ที่เปิดใช้งานจะเชื่อมต่อกับ stdout / stderr / stdin ของกระบวนการที่เริ่มต้นและจะยังคงทำงานต่อไปจนกว่าจะไม่มีสิ่งใดติดอยู่กับซ็อกเก็ตและเป็นลูก ๆ ที่ออกไปแล้ว กระบวนการ deamon ที่ดีจะช่วยให้มั่นใจได้ว่าจะไม่รอให้เด็กออกจากกระบวนการส้อมกระบวนการเด็กแล้วจึงออก เมื่ออยู่ในโหมดนี้จะไม่มีการส่ง SIGHUP ไปยังกระบวนการลูกโดย SSH ฉันเชื่อว่านี่จะทำงานได้อย่างถูกต้องสำหรับสคริปต์ส่วนใหญ่ที่ใช้กระบวนการที่จัดการทำลายตัวเองและไม่จำเป็นต้องมีพื้นหลัง ตำแหน่งที่สคริปต์เริ่มต้นใช้ '&' เพื่อแบ็กกราวน์โปรเซสเป็นไปได้ว่าปัญหาหลักคือว่ากระบวนการที่แบ็กกราวน์เคยพยายามอ่านจาก stdin หรือไม่เพราะจะทำให้เกิด SIGHUP หากเซสชันนั้นถูกยกเลิก

pty / tty = true *

หากสคริปต์ init เป็นพื้นหลังของกระบวนการที่เริ่มต้นเชลล์ BASH หลักจะส่งคืนรหัสออกไปยังการเชื่อมต่อ SSH ซึ่งจะเปลี่ยนเป็นทางออกทันทีเนื่องจากไม่รอให้กระบวนการลูกหยุดและไม่ถูกบล็อกใน stdout / stderr / stdin สิ่งนี้จะทำให้ SIGHUP ถูกส่งไปยังกลุ่มกระบวนการเปลือก bash หลักซึ่งเนื่องจากการควบคุมงานถูกปิดใช้งานในโหมดที่ไม่ใช่แบบโต้ตอบใน bash จะรวมถึงกระบวนการลูกเพิ่งเปิดตัว โดยที่ daemon โปรเซสเริ่มเซสชันกระบวนการใหม่อย่างชัดเจนเมื่อฟอร์กหรือในกระบวนการที่แยกกันมิฉะนั้นลูกของมันจะไม่ได้รับ SIGHUP จากกระบวนการพาเรนต์ BASH ที่ออก หมายเหตุนี่แตกต่างจากงานที่ถูกระงับซึ่งจะเห็น SIGTERM ฉันสงสัยว่าปัญหาเกี่ยวกับการทำงานนี้บางครั้งจะต้องเกี่ยวข้องกับสภาพการแข่งขันเล็กน้อย http://www.itp.uzh.ch/~dpotter/howto/daemonizeคุณจะเห็นว่าในรหัสที่เซสชันใหม่ถูกสร้างขึ้นโดยกระบวนการทางแยกซึ่งอาจไม่สามารถทำงานได้ก่อนที่ผู้ปกครองจะออกจึงทำให้เกิดการสุ่ม พฤติกรรมที่เหมาะสม / ล้มเหลวดังกล่าวข้างต้น คำสั่ง sleep จะช่วยให้มีเวลาเพียงพอสำหรับกระบวนการ forked ในการสร้างเซสชั่นใหม่ซึ่งเป็นสาเหตุที่มันใช้งานได้ในบางกรณี

pty / tty = true และการควบคุมงานเปิดใช้งานอย่างชัดเจนใน bash

SSH จะไม่เชื่อมต่อกับ stdout / stderr / stdin ของ bash shell หรือกระบวนการลูกที่เปิดตัวใด ๆ ซึ่งจะหมายถึงว่ามันจะออกจากทันทีที่ parent bash shell เริ่มดำเนินการตามคำสั่งที่ร้องขอ ในกรณีนี้เมื่อเปิดใช้งานการควบคุมงานอย่างชัดเจนกระบวนการใด ๆ ที่เปิดใช้งานโดย bash shell ที่มี '&' เป็นแบ็คกราวน์จะถูกวางลงในเซสชันที่แยกต่างหากทันทีและจะไม่ได้รับสัญญาณ SIGHUP เมื่อกระบวนการหลักไปยังเซสชัน BASH ออก ( การเชื่อมต่อ SSH ในกรณีนี้)

สิ่งที่จำเป็นต้องแก้ไข

ฉันคิดว่าวิธีการแก้ปัญหาจะต้องมีการกล่าวถึงอย่างชัดเจนในเอกสารประกอบการทำงาน / sudo เป็นกรณีพิเศษเมื่อทำงานกับกระบวนการ / บริการเบื้องหลัง โดยทั่วไปใช้ 'pty = false' หรือที่เป็นไปไม่ได้เปิดใช้งานการควบคุมงานอย่างชัดเจนว่าเป็นคำสั่งแรกและพฤติกรรมจะถูกต้อง

จากhttps://github.com/fabric/fabric/issues/395

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