วิธีตรวจสอบที่เหมาะสมว่า PID กำลังทำงานอย่างไร


12

ฉันมี.pidไฟล์และฉันต้องตรวจสอบว่ากระบวนการทำงานอยู่หรือไม่ จนถึงตอนนี้ฉันพบสองตัวเลือก

kill -0 `cat something.pid`

ซึ่งพิมพ์ข้อผิดพลาดหาก pid ไม่ทำงาน ฉันรู้ว่านี่สามารถเปลี่ยนเส้นทางไปยัง/dev/nullแต่มันทำให้ฉันคิดว่านี่ไม่ใช่ทางออกที่ดีที่สุด

ทางออกที่สองคือการใช้psซึ่งยังพิมพ์บน STDOUT

ps -ef `cat something.pid`

เป็นเรื่องปกติหรือไม่ที่จะเปลี่ยนเส้นทางเอาต์พุตไป/dev/nullและใช้รหัสสถานะที่ส่งคืนหรือเป็นสัญญาณว่าฉันกำลังทำอะไรผิดพลาดและฉันต้องการคำสั่งอื่นหรือไม่


5
ใช้kill -0เนื่องจากเป็นมาตรฐาน (POSIX) - เป็นไปตามมาตรฐาน
Anders

เกี่ยวข้อง: stackoverflow.com/questions/3043978/…
wisbucky

คำตอบ:


10

สำหรับ linux distros ที่ระบุ / proc / {pid} เป็นวิธีที่ดีในการรับข้อมูลเกี่ยวกับกระบวนการที่กำลังทำงานอยู่และโดยปกติแล้วคำสั่ง userspace เช่น "ps" กำลังสื่อสารกับเคอร์เนลอย่างไร ตัวอย่างเช่นคุณสามารถทำได้

[ -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"

แก้ไข: คุณควรตรวจสอบว่ามีการตั้งค่า kpid แต่สิ่งนี้มีประโยชน์มากกว่าเนื่องจากจะส่งคืน "ไม่มีอยู่" เพื่อยกเลิกการตั้งค่า $ {kpid}

[ -n "${kpid}" -a -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"

@SteveMuster นี่จะทำให้คำตอบเฉพาะสำหรับ Linux ไม่มี / proc บน OSX และฉันคิดว่าไม่มี / proc บน BSD
แอช

หมายเหตุด้วยสิ่งนี้คุณต้องแน่ใจว่า${kpid}มีอยู่
วิลฟ์

@Wilf ฉันแก้ไขมันเพื่อให้มันกลับกระบวนการ "ไม่อยู่" สำหรับล้าง $ {kpid}
ทอม H

ขอบคุณ - ผมทำสคริปต์ที่การตรวจสอบ PID โดยใช้วิธีการที่คล้ายกันและมันก็ไม่ได้ทำงานจนฉันพบนี้เป็นปัญหา :)
วิลฟ์

6

ดังที่ Anders ระบุไว้คุณควรใช้kill -0สำหรับการปฏิบัติตาม POSIX

บนระบบ Linux คุณสามารถตรวจสอบการมีอยู่ของไฟล์ในระบบไฟล์ / proc เช่น

-f /proc/$(cat something.pid)/status

1

หากเป็นสคริปต์ (ซึ่งฉันคิดว่าเป็นกรณีที่คุณกังวลเกี่ยวกับการพิมพ์เพื่อ stdout) แล้วต่อไปนี้จะเป็นวิธีที่คุณสามารถทำได้:

if ps -p $(cat something.pid) > /dev/null 2>&1
then
    kill $(cat something.pid)
else
    # Deal with the fact that the process isn't running
    # i.e. clear up the pid file
fi

ps -pลักษณะกระบวนการด้วย pid ที่ระบุไว้ใน something.pid A ( $()ไวยากรณ์เป็นรุ่นที่ใหม่กว่าเล็กน้อย backtick ได้. Backtick ต้องการหลบหนีในบางสถานการณ์ที่รูปแบบใหม่ไม่ได้) การ2>&1เปลี่ยนเส้นทาง stderr สำหรับคำสั่งนั้นเช่นกัน

หากps -pคำสั่งไม่พบกระบวนการที่มี PID นั้นมันจะออกพร้อมกับข้อผิดพลาด> 0 และเพื่อให้elseได้รับการดำเนินการ มิฉะนั้นkillคำสั่ง คุณสามารถคัดค้านข้างต้นหากคุณต้องการโดยทำ:

if ! ps -p ...

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


1

นี่คือตัวเลือกบางส่วน:

  • หากคุณกำลังเขียนสคริปต์เริ่มต้น (เช่นที่จะวางใน/etc/init.d/) และถ้าคุณกำลังใช้ Distrobased Debian คุณควรใช้start-stop-daemon:
    # start-stop-daemon -T -p $PIDFILE -u $USER_NAME -n $NAME
    คุณควรได้รหัสทางออก 0 ถ้ามันทำงานอยู่
  • คุณสามารถใช้ pgrep และ pkill จากprocpsแพ็คเกจ:
    pgrep --pidfile $PIDFILE

0

หากคุณมีไฟล์ pid คุณสามารถใช้ pgrep เพื่อตรวจสอบว่ากระบวนการกำลังทำงานอยู่หรือไม่:

    if pgrep -F something.pid; then
        echo "Running"
    else
        echo "Not running"
    fi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.