ในทางปฏิบัติฉันต้องการกระบวนการที่ทำงานเหมือนกับว่าฉันกดCtrl+Z
หลังจากเริ่ม
หวังว่ามันเป็นไปได้ที่จะทำสิ่งนี้โดยใช้เชลล์สคริปต์
(และการรู้ PID ที่เกิดขึ้นจะดีมากดังนั้นฉันจึงสามารถดำเนินการต่อได้ในภายหลัง)
ในทางปฏิบัติฉันต้องการกระบวนการที่ทำงานเหมือนกับว่าฉันกดCtrl+Z
หลังจากเริ่ม
หวังว่ามันเป็นไปได้ที่จะทำสิ่งนี้โดยใช้เชลล์สคริปต์
(และการรู้ PID ที่เกิดขึ้นจะดีมากดังนั้นฉันจึงสามารถดำเนินการต่อได้ในภายหลัง)
คำตอบ:
หลังจากเริ่มต้นกระบวนการคุณสามารถส่ง SIGSTOP เพื่อระงับมัน หากต้องการดำเนินการต่อให้ส่ง SIGCONT ฉันคิดว่าสคริปต์ตัวนี้อาจช่วยคุณได้
#!/bin/bash
$@ &
PID=$!
kill -STOP $PID
echo $PID
wait $PID
มันรันกระบวนการ (คำสั่งส่งเป็นพารามิเตอร์) หยุดชั่วคราวพิมพ์รหัสกระบวนการและรอจนกว่าจะสิ้นสุด
คุณสร้างกระบวนการจากสภาพแวดล้อมใด
หากคุณกำลังทำจากสภาพแวดล้อมเช่นรหัส C คุณสามารถแยก () และจากนั้นในเด็กส่ง SIGSTOP ให้กับตัวเองก่อนที่ exec () ป้องกันการดำเนินการต่อไป
วิธีแก้ปัญหาทั่วไปเพิ่มเติม (น่าจะดีที่สุด) คือการสร้างส่วนที่ทำเช่นนั้น ดังนั้นโปรแกรม stub จะ:
สิ่งนี้จะช่วยให้แน่ใจว่าคุณหลีกเลี่ยงเงื่อนไขการแข่งขันใด ๆ ที่เกี่ยวข้องกับการประมวลผลใหม่ที่ไกลเกินไปก่อนที่คุณจะสามารถส่งสัญญาณได้
ตัวอย่างสำหรับเชลล์:
#!/bin/bash
kill -STOP $$
exec "$@"
และใช้รหัสข้างต้น:
michael@challenger:~$ ./stopcall.sh ls -al stopcall.sh
[1]+ Stopped ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$ jobs -l
[1]+ 23143 Stopped (signal) ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$ kill -CONT 23143; sleep 1
-rwxr-xr-x 1 michael users 36 2011-07-24 22:48 stopcall.sh
[1]+ Done ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$
การjobs -l
แสดง PID แต่ถ้าคุณทำจากเปลือกคุณไม่จำเป็นต้องใช้ PID โดยตรง คุณสามารถทำได้: kill -CONT %1
(สมมติว่าคุณมีเพียงงานเดียว)
ทำมากกว่าหนึ่งงานหรือไม่? ทิ้งไว้เป็นแบบฝึกหัดสำหรับผู้อ่าน :)
คำตอบของ MikeyB นั้นถูกต้อง จากคำถามนี้ใน superuser นี่เป็นเวอร์ชั่นที่กระชับกว่านี้:
( kill -SIGSTOP $BASHPID; exec my_command ) &
เพื่อให้เข้าใจสิ่งนี้เราต้องเข้าใจว่ากระบวนการเริ่มต้นในยูนิกซ์ได้อย่างไร: การexec
เรียกของระบบจะแทนที่โปรแกรมที่กำลังทำงานอยู่ในปัจจุบันด้วยโปรแกรมใหม่โดยรักษา PID ที่มีอยู่เดิมไว้ ดังนั้นวิธีการสร้างกระบวนการอิสระคือก่อนfork
แล้วจึงexec
แทนที่โปรแกรมที่กำลังทำงานอยู่ในกระบวนการลูกด้วยโปรแกรมที่ต้องการ
ส่วนผสมของคำสั่งเชลล์นี้คือ:
(...)
เริ่มต้นเชลล์ย่อย: อินสแตนซ์อื่นของ BASHkill
คำสั่งส่งสัญญาณ STOP เพื่อกระบวนการนี้ซึ่งทำให้มันเป็นรัฐที่ถูกระงับCONT
สัญญาณ) exec
คำสั่งจะทำให้กระบวนการแทนที่ตัวเองด้วยโปรแกรมที่คุณต้องการ my_command
เก็บ PID ดั้งเดิมของ sub-shell$!
ตัวแปรเพื่อรับ PID ของกระบวนการ-s STOP
แทน-SIGSTOP
) ยังสงสัย: ทำไมต้องเป็น$BASHPID
แทน$$
? (ฉันอาจไม่เข้าใจความแตกต่างจริงๆ)
$$
vs $BASHPID
ฉันตรวจสอบอย่างหลังคือ PID ของ sub-shell ในขณะที่ไม่ใช่แบบเดิม มีปัญหาตลกคือ: การใช้เคล็ดลับในสคริปต์ทุบตีมักล้มเหลวและฉันต้องทำสิ่งนี้: PID=$!; ps -p $PID; kill -s CONT $PID;
... มันล้มเหลวถ้าฉันลบps -p $PID
ส่วน: กระบวนการดูเหมือนจะหายไป (ฆ่า?) โดยไม่มีข้อผิดพลาดที่ใดก็ได้ . ไม่เป็นไรจากเชลล์แบบโต้ตอบปัญหามาจากสคริปต์เท่านั้น มันลึกลับมากเกินไป
#!/bin/bash
[enter]$@ &
[enter]PID=$!
[enter]kill -STOP $PID
[enter]echo "Suspended: $PID, press ENTER to continue it"
[enter]read
[enter]kill -CONT $PID
[enter]wait $PID
[enter] [enter]echo