ในสคริปต์ทุบตีฉันต้องการทำดังต่อไปนี้ (ในรหัสหลอก):
if [ a process exists with $PID ]; then
kill $PID
fi
การแสดงออกที่เหมาะสมสำหรับคำสั่งเงื่อนไขคืออะไร?
ในสคริปต์ทุบตีฉันต้องการทำดังต่อไปนี้ (ในรหัสหลอก):
if [ a process exists with $PID ]; then
kill $PID
fi
การแสดงออกที่เหมาะสมสำหรับคำสั่งเงื่อนไขคืออะไร?
คำตอบ:
เพื่อตรวจสอบการมีอยู่ของกระบวนการใช้
kill -0 $pid
แต่อย่างที่ @unwind พูดถ้าคุณจะฆ่ามันล่ะ
kill $pid
หรือคุณจะมีสภาพการแข่งขัน
หากคุณต้องการที่จะละเว้นการส่งออกข้อความของkill
และทำอะไรบางอย่างตามรหัสออกคุณสามารถ
if ! kill $pid > /dev/null 2>&1; then
echo "Could not send SIGTERM to process $pid" >&2
fi
kill
ค่อนข้างผิดที่ไม่จำเป็นต้องฆ่ากระบวนการ มันเพิ่งส่งสัญญาณกระบวนการ kill $PID
เทียบเท่ากับkill -15 $PID
ซึ่งส่งสัญญาณ 15, SIGTERM ไปยังกระบวนการซึ่งเป็นคำสั่งให้ยุติ ไม่มีสัญญาณ 0 นั่นคือค่าพิเศษที่บอกkill
ให้ตรวจสอบว่าสามารถส่งสัญญาณไปยังกระบวนการได้หรือไม่ซึ่งมีจุดประสงค์ส่วนใหญ่มากกว่าหรือน้อยกว่าเทียบเท่ากับการตรวจสอบว่ามีอยู่หรือไม่ ดูlinux.die.net/man/2/killและlinux.die.net/man/7/signal
kill -0
แล้วฉันต้องทำสิ่งนี้: kill -0 25667 ; echo $?
- แล้วถ้าฉันได้รับ0
คืนจากนั้นกระบวนการที่มี PID นั้นจะถูกฆ่า; และถ้ากระบวนการ PID (พูด) ไม่มีอยู่สิ่ง$?
นั้นจะ1
บ่งบอกถึงความล้มเหลว ถูกต้องไหม
วิธีที่ดีที่สุดคือ:
if ps -p $PID > /dev/null
then
echo "$PID is running"
# Do something knowing the pid exists, i.e. the process with $PID is running
fi
ปัญหากับ:
kill -0 $PID
คือรหัสทางออกจะไม่เป็นศูนย์แม้ว่า pid กำลังทำงานอยู่และคุณไม่ได้รับอนุญาตให้ฆ่ามัน ตัวอย่างเช่น:
kill -0 1
และ
kill -0 $non-running-pid
มีรหัสทางออกที่แยกไม่ออก (ไม่ใช่ศูนย์) สำหรับผู้ใช้ปกติ แต่กระบวนการเริ่มต้น (PID 1) กำลังทำงานอยู่อย่างแน่นอน
คำตอบเกี่ยวกับเงื่อนไขการฆ่าและการแข่งขันนั้นถูกต้องหากร่างของการทดสอบนั้นเป็น "การฆ่า" ฉันมาหาคำว่า " คุณจะทดสอบการมีอยู่ของ PID ได้อย่างไรในการทุบตี "
กระบวนการ / proc นั้นน่าสนใจ แต่ในบางแง่มุมทำให้จิตวิญญาณของคำสั่ง abstraction "ps" นั่นคือคุณไม่จำเป็นต้องค้นหา / proc เพราะถ้า Linus ตัดสินใจที่จะเรียกไฟล์ "exe" อย่างอื่น?
-p
มีความจำเป็นอย่างน้อยในกรณีนั้น ps $PID
มีผลลัพธ์เหมือนกันทุกประการ
if [ -n "$PID" -a -e /proc/$PID ]; then
echo "process exists"
fi
หรือ
if [ -n "$(ps -p $PID -o pid=)" ]
ในรูปแบบหลัง-o pid=
เป็นรูปแบบเอาต์พุตเพื่อแสดงเฉพาะคอลัมน์ ID กระบวนการที่ไม่มีส่วนหัว เครื่องหมายคำพูดจำเป็นสำหรับตัวดำเนินการสตริงที่ไม่ว่างเปล่า-n
เพื่อให้ผลลัพธ์ที่ถูกต้อง
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
ps
ตัวเลือกและคุณสมบัติต่างๆนั้นมีความแตกต่างกันระหว่างแพลตฟอร์มดังนั้นจึงยังไม่สามารถพกพาได้ทั้งหมด
$PID
ว่างแล้ว[ -e /proc/$PID ]
จะยังคงเป็นจริงเนื่องจาก/proc/
ไดเรกทอรียังคงอยู่
ps
คำสั่งด้วย-p $PID
สามารถทำสิ่งนี้:
$ ps -p 3531
PID TTY TIME CMD
3531 ? 00:03:07 emacs
คุณมีสองวิธี:
เริ่มต้นด้วยการมองหาแอปพลิเคชันเฉพาะในแล็ปท็อปของฉัน:
[root@pinky:~]# ps fax | grep mozilla
3358 ? S 0:00 \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2 S+ 0:00 \_ grep mozilla
ตัวอย่างทั้งหมดในตอนนี้จะค้นหา PID 3358
วิธีแรก : เรียกใช้ "ps aux" และ grep สำหรับ PID ในคอลัมน์ที่สอง ในตัวอย่างนี้ฉันค้นหา firefox และจากนั้น PID:
[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358
ดังนั้นรหัสของคุณจะเป็น:
if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
kill $PID
fi
วิธีที่สอง : เพียงมองหาบางอย่างใน/proc/$PID
ไดเรกทอรี ฉันใช้ "exe" ในตัวอย่างนี้ แต่คุณสามารถใช้อย่างอื่นได้
[root@pinky:~]# ls -l /proc/3358/exe
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash
ดังนั้นรหัสของคุณจะเป็น:
if [ -f /proc/$PID/exe ]; then
kill $PID
fi
BTW: มีอะไรผิดปกติกับkill -9 $PID || true
?
แก้ไข:
หลังจากคิดถึงเรื่องนี้ไปซักสองสามเดือน .. (ประมาณ 24 ... ) ความคิดดั้งเดิมที่ฉันให้ที่นี่เป็นแฮ็คที่ดี แต่ไม่สามารถพูดได้สูง แม้ว่ามันจะสอนรายละเอียดเกี่ยวกับการใช้งานของลีนุกซ์ แต่ก็จะล้มเหลวในการทำงานบน Mac, Solaris หรือ * BSD มันอาจจะล้มเหลวในเมล็ด Linux ในอนาคต กรุณา - ใช้ "ps" ตามที่อธิบายไว้ในคำตอบอื่น ๆ
/proc/$PID/exe
ไม่ใช่ไฟล์ปกติ ดังนั้น[ -f /proc/$PID/exe ]
จะส่งคืนfalse
ผลลัพธ์เสมอ ลอง[ -h /proc/$PID/exe ]
ดู
ดูเหมือนว่าคุณต้องการ
wait $PID
ซึ่งจะกลับมาเมื่อ$pid
เสร็จสิ้น
มิฉะนั้นคุณสามารถใช้
ps -p $PID
เพื่อตรวจสอบว่ากระบวนการยังมีชีวิตอยู่หรือไม่ (นี่มีประสิทธิภาพมากกว่าkill -0 $pid
เพราะจะใช้ได้แม้ว่าคุณจะไม่ได้เป็นเจ้าของ pid)
pid 123 is not a child of this shell
ฉันคิดว่านั่นเป็นทางออกที่ไม่ดีที่เปิดขึ้นสำหรับสภาพการแข่งขัน ถ้ากระบวนการตายระหว่างการทดสอบและการเรียกร้องให้ฆ่า? จากนั้นการฆ่าจะล้มเหลว ดังนั้นทำไมไม่ลองฆ่าในทุกกรณีและตรวจสอบค่าตอบแทนเพื่อดูว่ามันไปได้อย่างไร
kill -9
อย่าลวก นั่นเป็นเพียงการฆ่ากระบวนการทันทีโดยไม่มีโอกาสที่จะทำความสะอาดหลังจากนั้น ใช้แทนซึ่งเทียบเท่ากับkill
kill -15
หากวิธีนี้ใช้ไม่ได้ผลคุณควรหาสาเหตุและใช้เพื่อการใช้งานครั้งสุดท้ายkill -9
เท่านั้น
ที่นี่ฉันเก็บ PID ในไฟล์ที่เรียกว่า. pid (ซึ่งเป็นประเภท like / run / ... ) และเรียกใช้สคริปต์เท่านั้นหากยังไม่ได้ดำเนินการ
#!/bin/bash
if [ -f .pid ]; then
read pid < .pid
echo $pid
ps -p $pid > /dev/null
r=$?
if [ $r -eq 0 ]; then
echo "$pid is currently running, not executing $0 twice, exiting now..."
exit 1
fi
fi
echo $$ > .pid
# do things here
rm .pid
หมายเหตุ:มีสภาพการแข่งขันเนื่องจากไม่ได้ตรวจสอบว่ามีการเรียก pid อย่างไร หากระบบรีบูตและมี. pid อยู่ แต่มีการใช้งานโดยแอปพลิเคชันอื่นซึ่งอาจนำไปสู่
ตัวอย่างเช่นใน GNU / Linux คุณสามารถใช้:
Pid=$(pidof `process_name`)
if [ $Pid > 0 ]; then
do something
else
do something
fi
หรืออะไรทำนองนั้น
Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN
และนั่นจะแสดงชื่อแอพให้คุณเห็นเพียงชื่อที่ไม่มี ID
pidof
จะไม่ส่งคืนจำนวนลบเนื่องจาก PID เชิงลบไม่ได้มีเหตุผลใด ๆ และคุณไม่สามารถฆ่าได้init
ดังนั้นเงื่อนไขของคุณจึงไม่สมเหตุสมผล (และนอกจากนี้คุณต้องหลีกเลี่ยง>
เพื่อป้องกันการเปลี่ยนเส้นทาง) คุณต้องการตรวจสอบผลลัพธ์ที่ว่างเปล่า แต่แน่นอนเช่นเดียวกับเครื่องมือที่ดีใด ๆpidof
ตั้งรหัสออกเพื่อบอกคุณว่ามันทำงานได้หรือไม่ดังนั้นทางออกที่เหมาะสมคือif Pid=$(pidof 'process_name'); then ...
หรือ (ถ้าคุณไม่ต้องการค่าในPid
ภายหลัง) เพียงแค่if pidof 'process_name'; then...
pidof
ตัวอย่างเต็มไปด้วยความเข้าใจผิดเกี่ยวกับวิธีการทุบตีtest
ทำงาน gnu.org/software/bash/manual/html_node/…
โค้ดด้านล่างตรวจสอบว่ากระบวนการของฉันทำงานอยู่หรือไม่
ลองตรวจสอบข้อความใหม่จาก Amazon SQS ทุก ๆ ชั่วโมงเท่านั้นและถ้ากระบวนการไม่ทำงาน
#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
/usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
echo "do nothing, just smile =)"
fi
exit $?