`kill -0 $ pid 'ในเชลล์สคริปต์ทำอะไร


139

โดยทั่วไปสัญญาณใดที่แสดงถึง '0' เพราะที่นี่ฉันเห็นตัวเลขสัญญาณเริ่มต้นจาก 1



2
เห็นแล้วยังแตกต่าง Unix.SE ของคำถามนี้ซึ่งแตกต่างจากkill 0(ไม่มีขีด) อธิบายที่นี่และที่นี่
Adam Katz

คำตอบ:


136

การส่งสัญญาณ0ไปยังที่ได้รับPIDเพียงแค่ตรวจสอบว่ากระบวนการใด ๆ ที่มีให้PIDกำลังทำงานอยู่และคุณมีสิทธิ์ในการส่งสัญญาณไปยังมัน

สำหรับข้อมูลเพิ่มเติมดู manpages ต่อไปนี้:

ฆ่า (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.
...

7
ตำแหน่งของข้อมูลนี้ (ถ้ามีอยู่ทั้งหมด) ขึ้นอยู่กับระบบอย่างสูง บนระบบที่ใช้ Debian ล่าสุดให้ใช้man 2 killแทน
Todd A. Jacobs

2
ทั้งคู่man 1 killและใช้man 2 killมันในระบบ Fedora 20 ของฉัน มันยากที่จะมองเห็นว่าฝังทั้งหน้าคน
slm

หรือพึ่งพาคู่มือ posix แทน: If sig is 0 (the null signal), error checking is performed but no signal is actually sent. The null signal can be used to check the validity of pid. pubs.opengroup.org/onlinepubs/009695399/functions/kill.html
Thomas Hughes

2
ฉันรู้สึกเหมือนคำสั่งman 2 killอยู่นอกการแก้ไข 1 :)
JBaczuk

126

นี่เป็นคำถามที่ดีเพราะ ...

... อาจเป็นเรื่องยากที่จะหาเอกสารเกี่ยวกับสัญญาณพิเศษนี้ แม้จะมีสิ่งที่คนอื่นพูด แต่การพูดถึงสัญญาณนี้man 1 killในระบบที่ใช้เดเบียนคือ:

สัญญาณที่มีประโยชน์อย่างยิ่ง ได้แก่ HUP, INT, KILL, STOP, CONT และ 0

ไม่เป็นประโยชน์โดยเฉพาะอย่างยิ่งโดยเฉพาะอย่างยิ่งถ้าคุณไม่ทราบว่าสัญญาณทำอะไร มันไม่ได้อยู่ในรายการผลลัพธ์kill -lดังนั้นคุณจะไม่รู้เกี่ยวกับมันจนกว่าคุณจะรู้แล้ว

จะหาเอกสารได้ที่ไหน

บนระบบ Debian และ Ubuntu ผลลัพธ์ของการman 2 killพูดส่วนที่:

หาก sig เป็น 0 จะไม่มีการส่งสัญญาณ แต่การตรวจสอบข้อผิดพลาดยังคงดำเนินการอยู่ สามารถใช้เพื่อตรวจสอบการมีอยู่ของ ID กระบวนการหรือ ID กลุ่มกระบวนการ

สิ่งที่ดีสำหรับ

คุณสามารถใช้kill -0เพื่อตรวจสอบว่ากระบวนการทำงานอยู่หรือไม่ ลองพิจารณาตัวอย่างเหล่านี้

# Kill the process if it exists and accepts signals from
# the current user.
sleep 60 &
pid=$!
kill -0 $pid && kill $pid

# Check if a PID exists. When missing, this should result
# in output similar to:
#    bash: kill: (6228) - No such process
#    Exit status: 1
kill -0 $pid; echo "Exit status: $?"

นอกจากนี้คุณยังสามารถใช้kill -0เพื่อตรวจสอบว่าผู้ใช้ปัจจุบันมีสิทธิ์ในการส่งสัญญาณกระบวนการที่กำหนด ตัวอย่างเช่น:

# See if you have permission to signal the process. If not,
# this should result in output similar to:
#     bash: kill: (15764) - Operation not permitted
#     Exit status: 1
sudo sleep 60 &
kill -0 $!; echo "Exit status: $?"

บน Mac และ BSD ก็ยังบันทึกไว้ในkill(2) ที่นี่เป็นข้อมูลโค้ด:The kill() function sends the signal specified by sig to pid, a process or a group of processes. Typically, Sig will be one of the signals specified in sigaction(2). A value of 0, however, will cause error checking to be performed (with no signal being sent). This can be used to check the validity of pid.
lukecampbell

8
นี่ควรเป็นคำตอบที่ยอมรับได้ ดีกว่าอีกอันมาก เอกสารเกี่ยวกับสัญญาณ 0 นั้นหายาก มันถูกฝังอยู่ในkillman page: "ถ้า sig เป็น 0 จะไม่มีการส่งสัญญาณ แต่การตรวจสอบข้อผิดพลาดยังคงดำเนินการอยู่"
slm

6

คำสั่งนี้ตรวจสอบว่ากระบวนการด้วย PID ใน $ pid ยังมีชีวิตอยู่


1
หน้าคนพูดว่า: "ถ้า sig เป็น 0 ดังนั้นจะไม่มีการส่งสัญญาณ แต่การตรวจสอบข้อผิดพลาดยังคงดำเนินการอยู่" เราหมายถึงการตรวจสอบข้อผิดพลาดอะไรที่นี่?
gjain

2
-1 เนื่องจากกระบวนการที่มี PID $pidอาจทำงานอยู่ แต่คุณไม่มีสิทธิ์ในการส่งสัญญาณ
dwalter

2
@dwalter: หากคุณไม่ได้รับอนุญาตคุณจะได้รับ EPERM หากไม่มีอยู่คุณจะได้รับ ESRCH kill(1)จะพิมพ์ข้อผิดพลาดที่แตกต่างกันสำหรับแต่ละ ดังนั้นคุณสามารถบอกได้ว่า pid ยังมีชีวิตอยู่ไม่ว่าคุณจะมีสิทธิ์ในการส่งสัญญาณหรือไม่ ยิ่งไปกว่านั้นการใช้งานทั่วไปของkill -0ดูว่า pid ยังมีชีวิตอยู่แม้ว่าจะไม่ได้ใช้อย่างถูกต้อง ฉันว่าคำตอบนี้ถูกต้อง (นอกเหนือจากการสะกดคำ)
camh

3
@camh: ไม่มีค่าตอบแทนของkill -0 $pidทั้งสองกรณี มันจะกลับมา1เพื่อให้คุณไม่สามารถพูดได้โดยไม่ต้องแยกวิเคราะห์ ouput killว่ากระบวนการทำงานหรือไม่ถ้าคุณไม่มีสิทธิ์ในการส่งสัญญาณไป แก้ไข: ใช่ฉันรู้ว่ามันใช้เวลาส่วนใหญ่ในการตรวจสอบว่ากระบวนการยังมีชีวิตอยู่หรือไม่ แต่นี่เป็นสิ่งที่ผิดเว้นแต่คุณจะสามารถรับประกันได้ว่าคุณได้รับอนุญาตให้ส่งสัญญาณ (เช่น: เป็นรูท)
dwalter

2
@dwalter: ประเด็นของฉันคือคำตอบนั้นถูกต้อง คุณพยายามที่จะอวดความคิดและชี้ให้เห็นว่ามีกรณีข้อผิดพลาดอื่น แต่ฉันบอกคุณว่าในทางเทคนิคคำตอบครอบคลุมกรณีเช่นกันตั้งแต่killทุบตีในตัว (คำถามที่ติดแท็กbash) เอาท์พุทประเภทของข้อผิดพลาดใน stderr และบ่งชี้ ของข้อผิดพลาดในรหัสส่งคืน นั่นคือ "คำสั่งนี้ตรวจสอบ [ว่า] กระบวนการที่มี PID ใน $ pid ยังมีชีวิตอยู่" ถูกต้องสมบูรณ์หากคุณตีความผลลัพธ์ได้อย่างถูกต้อง [ฉันจะไม่ได้แสดงความคิดเห็นถ้าคุณไม่ได้บอกว่าคุณให้ -1 คำตอบ ความคิดเห็นของคุณไม่ถูกต้อง]
camh

6

กำจัด -0 $ pid คือการตรวจสอบว่ากระบวนการที่มี pid นั้นมีอยู่หรือไม่

ระมัดระวังในขณะที่ใช้ 'kill -0 $ pid' เพื่อตรวจสอบการมีอยู่ของกระบวนการเพราะ

  1. เมื่อกระบวนการที่ต้องการออกจากนั้น pid ของมันสามารถจัดสรรให้กับกระบวนการที่สร้างขึ้นใหม่ (ดังนั้นจึงไม่สามารถมั่นใจได้ว่ากระบวนการเฉพาะนั้นยังมีชีวิตอยู่หรือไม่)

  2. ในกรณีของกระบวนการซอมบี้ที่เด็กกำลังรอให้ผู้ปกครองโทรหารอ ที่นี่จะถือ $ pid และให้ผลลัพธ์ที่เป็นบวกในขณะที่กระบวนการนั้นไม่ได้ทำงาน


1

กำจัด -0 $ pid ที่ใช้เพื่อตรวจสอบว่ากระบวนการที่ใช้ $ pid ยังมีชีวิตอยู่หรือไม่ แต่นี่อาจเป็นเรื่องยุ่งยากเนื่องจาก ID กระบวนการสามารถกำหนดใหม่ได้เมื่อการออกจากกระบวนการและกระบวนการใหม่ทำงาน หนึ่งสามารถใช้ killall -0 เพื่อรับเกี่ยวกับกระบวนการเฉพาะกำลังทำงานอยู่หรือไม่


0

การส่งEXITสัญญาณหรือ0กระบวนการจะ:

  1. ตรวจสอบการมีอยู่ของกระบวนการ
  2. ทำการตรวจสอบข้อผิดพลาดต่าง ๆ เกี่ยวกับกระบวนการ (PID, PGID, ฯลฯ ... )
  3. มันจะไม่ส่งผลลัพธ์ใด ๆ ไปสู่stdoutความสำเร็จ
  4. ส่งข้อความแสดงข้อผิดพลาดstderrหากมีบางอย่างไม่ถูกต้อง
  5. ให้ผลบวกเป็นเท็จหากกระบวนการนี้หมดอายุ (เช่น Zombie)

ชัดเจนกว่าฟังก์ชั่นที่มีประโยชน์สำหรับเชลล์สคริปต์ของคุณคือ:

function isProcess ()
{
    kill -s EXIT $1 2> /dev/null
}

สิ่งนี้จะไม่ส่งข้อความถึงstdoutเมื่อสำเร็จ แต่ข้อความแสดงข้อผิดพลาดไปยังstderrเมื่อเกิดความล้มเหลว (แต่ฉันเปลี่ยนเส้นทางข้อความแสดงข้อผิดพลาดนั้นไป/dev/null)

หากคุณมีความกังวลเกี่ยวกับสถานะกระบวนการตาย / ซอมบี้คุณต้องใช้psโดยเฉพาะอย่างยิ่งกับ--no-headersสวิตช์

#!/bin/ksh

function trim ()
{
    echo -n "$1" | tr -d [:space:]
}

function getProcessStatus ()
{
    trim $(ps -p $1 -o stat --no-headers)
}

function isZombie ()
{
    typeset processStatus=$(getProcessStatus $1)

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