ฉันเพิ่งเจอสิ่งนี้ในเชลล์สคริปต์
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
อะไรkill -0 ...
ทำอย่างไร
kill -0 $pid
ในสคริปต์เปลือกทำอย่างไร เช่นเดียวกับสิ่งที่ไม่ฆ่า 0 ทำจริง? .
ฉันเพิ่งเจอสิ่งนี้ในเชลล์สคริปต์
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
อะไรkill -0 ...
ทำอย่างไร
kill -0 $pid
ในสคริปต์เปลือกทำอย่างไร เช่นเดียวกับสิ่งที่ไม่ฆ่า 0 ทำจริง? .
คำตอบ:
อันนี้ค่อนข้างยากที่จะรวบรวม แต่ถ้าคุณดูใน 2 man pages ต่อไปนี้คุณจะเห็นหมายเหตุต่อไปนี้:
ฆ่า (1)$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
ฆ่า (2)
$ man 2 kill
...
If sig is 0, then no signal is sent, but error checking is still performed;
this can be used to check for the existence of a process ID or process
group ID.
...
ดังนั้นสัญญาณ 0 จะไม่ส่งสิ่งใด ๆ ไปยัง PID ของกระบวนการจริง ๆ แต่จะตรวจสอบว่าคุณมีสิทธิ์ในการทำเช่นนั้นหรือไม่
สถานที่หนึ่งที่ชัดเจนคือถ้าคุณพยายามตรวจสอบว่าคุณมีสิทธิ์ในการส่งสัญญาณไปยังกระบวนการที่ทำงานอยู่kill
หรือไม่ คุณสามารถตรวจสอบก่อนที่จะส่งkill
สัญญาณจริงที่คุณต้องการโดยการตรวจสอบเพื่อให้แน่ใจว่าkill -0 <PID>
ได้รับอนุญาตก่อน
บอกว่ากระบวนการกำลังถูกรูทโดยดังนี้:
$ sudo sleep 2500 &
[1] 15693
ตอนนี้ในหน้าต่างอื่นถ้าเราเรียกใช้คำสั่งนี้เราสามารถยืนยันได้ว่า PID กำลังทำงานอยู่
$ pgrep sleep
15693
ทีนี้ลองคำสั่งนี้ดูว่าเราสามารถส่งสัญญาณ PID kill
นั้นได้หรือไม่
$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!
ดังนั้นจึงใช้งานได้ แต่เอาต์พุตกำลังรั่วข้อความจากkill
คำสั่งที่เราไม่มีสิทธิ์ใช้งาน ไม่ได้เป็นเรื่องใหญ่ก็จับ STDERR /dev/null
และส่งไปยัง
$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!
ดังนั้นเราจึงสามารถทำสิ่งนี้killer.bash
:
#!/bin/bash
PID=$(pgrep sleep)
if ! kill -0 $PID 2>/dev/null; then
echo "you don't have permissions to kill PID:$PID"
exit 1
fi
kill -9 $PID
ตอนนี้เมื่อฉันเรียกใช้ข้างต้นเป็นผู้ใช้ที่ไม่ใช่รูท:
$ ~/killer.bash
you don't have permissions to kill PID:15693
$ echo $?
1
อย่างไรก็ตามเมื่อมันรันเป็นรูท:
$ sudo ~/killer.bash
$ echo $?
0
$ pgrep sleep
$
pgrep
, ps
การแยกหรือtest -e /proc/$PID
ใน scrips แบบพกพา แต่kill -0
ทำงานได้ทุกที่ หากคุณได้รับ PID ที่อาจค้าง - เช่น/var/run
รายการ - นี่เป็นวิธีพกพาเพื่อตรวจสอบว่ากระบวนการยังมีชีวิตอยู่หรือไม่
kill -0 $(pgrep sleep)
อาจไม่ได้หมายความว่าคุณกำลังอ่อนแอมันจะกลับมาผิดพลาดหากไม่มีsleep
คำสั่งทำงานหรือมีมากกว่าหนึ่งและมีสิ่งหนึ่งที่คุณไม่สามารถฆ่าได้หรือถ้าหนึ่งในสลีปเสียชีวิตระหว่าง pgrep และการฆ่า คำสั่งถูกเรียกใช้
kill -0
(หรือตัวแปร POSIX แบบพกพามากกว่าkill -s 0
) ผ่านการเคลื่อนที่ของการส่งสัญญาณ แต่ไม่ได้ส่งสัญญาณ มันเป็นคุณสมบัติของC API พื้นฐานที่คำสั่งเชลล์เปิดเผยในลักษณะที่ตรงไปตรงมา
kill -s 0 -- "$pid"
ดังนั้นทดสอบว่ามีกระบวนการทำงานด้วย PID ที่กำหนด (หรือ PGID ถ้า$pid
เป็นลบ) หรือไม่และกระบวนการปัจจุบันจะได้รับอนุญาตให้ส่งหรือไม่ (กระบวนการใด ๆ ในกลุ่มกระบวนการในกรณีที่$pid
มีสัญญาณลบ) ส่วนใหญ่เป็นวิธีการทดสอบว่ากระบวนการ (หรือกลุ่มกระบวนการ) ยังมีชีวิตอยู่
โปรดจำไว้ว่าแม้ว่าจะมีกระบวนการทำงานที่มี PID และการอนุญาตที่คาดหวัง แต่ก็ไม่จำเป็นต้องเป็นกระบวนการที่คุณคาดหวัง เป็นไปได้ว่ากระบวนการที่คุณคาดว่าจะตายก่อนหน้านี้และ PID ของมันถูกนำมาใช้ใหม่สำหรับกระบวนการที่ไม่เกี่ยวข้อง วิธีที่ถูกต้องในการตรวจสอบกระบวนการคือให้พ่อแม่ทำ - PID ของกระบวนการจะไม่ถูกนำมาใช้ซ้ำจนกว่าพ่อแม่จะยอมรับการตาย (นั่นคือสาเหตุที่ซอมบี้อยู่) ดังนั้นผู้ปกครองของกระบวนการสามารถระบุลูก ๆ
กระบวนการkill -0 $pid
จะบอกคุณว่ากระบวนการที่มี$pid
อยู่หรือไม่
ในตัวอย่าง
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
บล็อก... do something ...
จะถูกดำเนินการหากกระบวนการที่มี PID ที่เก็บอยู่/path/to/file.pid
นั้นกำลังทำงานอยู่ - และ - ยกเว้นว่าข้อมูลโค้ดนั้นทำงานเป็นรูท - หาก PID นั้นทำงานภายใต้ผู้ใช้รายเดียวกัน
มาตรฐาน POSIX ระบุบทบาทของ0
สัญญาณ:
หาก sig เป็น 0 (สัญญาณว่าง) การตรวจสอบข้อผิดพลาดจะดำเนินการ แต่ไม่มีการส่งสัญญาณใด ๆ สัญญาณว่างสามารถใช้เพื่อตรวจสอบความถูกต้องของ pid
(kill (3p), POSIX.1-2008 - ถ้อยคำที่คล้ายกันใน POSIX.1-2001)
โปรดทราบว่า POSIX ระบุทั้งสไตล์kill -0
และkill -s 0
บรรทัดคำสั่ง (kill (1p))
ตรงกันข้ามกับ kill syscall interface kill
ไม่สามารถใช้คำสั่งเพื่อตรวจสอบการมีอยู่ของ PID ที่ผู้ใช้รายอื่นเป็นผู้ใช้ (ในฐานะผู้ใช้ทั่วไป) ได้อย่างน่าเชื่อถือเช่น:
$ kill -0 123
kill: kill 123 failed: no such process
$ echo $?
1
เมื่อเทียบกับ
$ kill -0 1
kill: kill 1 failed: operation not permitted
$ echo $?
1
เมื่อเรียกใช้ kill syscall สามารถแยกแยะกรณีเหล่านี้ได้อย่างน่าเชื่อถือผ่านการดูerrno
ค่า (เช่นตัวอย่าง Python )
trap
คำสั่งBash และ 0 กับสัญญาณ 0 จากkill
: สัญญาณ 0 ในคำสั่ง Trap คืออะไร