เป็นวิธีการตรวจสอบว่ากระบวนการกำลังทำงานอยู่ในพื้นหลัง (และข้ามการดำเนินการใหม่ตามนั้นหรือไม่)


11

ฉันสามารถสร้างบรรทัดคำสั่ง bash ที่รันเฉพาะคำสั่งบางอย่างได้หรือไม่หากกระบวนการยังไม่ได้ทำงาน (อยู่เบื้องหลัง)

ฉันจะตรวจสอบได้อย่างไร * หากคำสั่งทำงานอยู่แล้ว

(ดังนั้นฉันสามารถเพิ่มคำสั่งถัดไปด้วย&&ในระหว่างพวกเขาดังนั้นคนต่อไปจะดำเนินการเฉพาะถ้าคนแรกเป็นจริง)

*: ทดสอบกำหนดค้นหาค้นพบ


3
ps -ef | grep -v grep | grep "process_name" || run_command_here
ราหุลปาติล

1
@RahulPatil คุณสามารถใช้pgrep "process_name"แทนps | grep | grep
เร่ง

อืมฉันลืมไปเลยว่า .. : D
Rahul Patil

1
ทำไมคุณไม่ใช้ไฟล์ "ล็อค" และเมื่อคุณเปิดใช้งานครั้งที่สองมันจะเปิดเฉพาะเมื่อไฟล์ล็อคหายไป
BitsOfNix

วิธีที่ดีที่สุดในการตรวจสอบว่ากระบวนการนั้นมีอยู่หรือไม่: stackoverflow.com/questions/3043978/…
เทรเวอร์บอยด์สมิ ธ

คำตอบ:


6

3

ฉันใช้เทคนิคนี้เป็นครั้งคราว:

$ pgrep <process name> || <process name>

ก่อนหน้าpgrepนี้เคยใช้วิธีนี้มาก่อน:

$ ps -eaf | grep -q <[p]rocess name> || <process name>

ตัวอย่าง

บิตด้วยการ[p]ทำให้มันเพื่อที่grepจะไม่พบว่าตัวเองเป็นผล

$ ps -eaf | grep -q [s]leep || sleep 10

2

สิ่งนี้อาจเป็นเรื่องยุ่งยากเนื่องจากคุณสามารถแยกอินสแตนซ์ของกระบวนการเดียวกันที่แยกกันอยู่โดยอิสระ ตัวอย่างเช่นเซิร์ฟเวอร์ที่กำลังฟังพอร์ตต่าง ๆ หรือบริการที่ทำงานในฐานะผู้ใช้ที่ต่างกัน เพื่อที่จะแยกแยะความแตกต่างระหว่างอินสแตนซ์เหล่านี้คุณต้องกำหนดแท็กที่ไม่ซ้ำกันให้แต่ละอัน แท็กมักจะเป็นไฟล์ แต่สามารถเป็นซ็อกเก็ตในพื้นที่ใน namespace นามธรรม, พอร์ต TCP, ฯลฯ - ตัวระบุที่ไม่ซ้ำกันจะทำ เมื่อแท็กเป็นไฟล์ไฟล์นั้นอาจเป็นไฟล์ปกติที่มี ID กระบวนการ (pidfile) หรือไพพ์ที่มีชื่อหรือไฟล์ที่ซ็อคเก็ตที่ไฟล์กำลังฟังอยู่เป็นต้นโดยปกติแล้วแท็กคือจุดสิ้นสุดการสื่อสารที่อนุญาตให้ไคลเอนต์เชื่อมต่อ กับกระบวนการนั้น

แท็กประเภทต่าง ๆ เหล่านี้ส่งผลให้เกิดวิธีตรวจสอบว่าอินสแตนซ์ที่คุณค้นหากำลังทำงานอยู่หรือไม่ ตัวอย่างเช่นใช้ซ็อกเก็ตไฟล์ในเครื่องพยายามเชื่อมต่อกับซ็อกเก็ตนั้นและเริ่มต้นกระบวนการหากไม่มีกระบวนการรับฟังจากซ็อกเก็ตนั้น หากแท็กเป็น pidfile ให้ตรวจสอบว่ามีกระบวนการที่มี ID กระบวนการนั้นหรือไม่ แต่ระวังว่านี่เป็นกระบวนการที่เปราะบางเนื่องจากหากกระบวนการนั้นเสียชีวิต ระวังว่าหากลูกค้าสองรายพยายามเข้าถึงกระบวนการในช่วงเวลาอันสั้นพวกเขาทั้งสองอาจพบว่ากระบวนการนั้นไม่มีอยู่และทั้งคู่พยายามที่จะเริ่มกระบวนการ การปกป้องอย่างถูกต้องจากสภาพการแข่งขันนี้อาจเป็นเรื่องยุ่งยาก

ง่ายต่อการจัดการอินสแตนซ์เมื่อพวกเขาทั้งหมดเริ่มต้นโดยกระบวนการของผู้ดูแลระบบเดียวกันและกระบวนการของผู้ดูแลนั้นจะตรวจพบเมื่ออินสแตนซ์ตายและตอบสนองตามนั้น โปรแกรมตรวจสอบบริการจำนวนมากที่สามารถทำได้

หากโปรแกรมไม่ตอบสนองต่อจุดปลายการสื่อสารที่รู้จักและไม่ได้รับการจัดการโดยโปรแกรมผู้ดูแลระบบแท็กของคนจนคือ pidfile: ไฟล์ที่มี ID กระบวนการ เมื่อคุณเริ่มกระบวนการเขียน pid ไปยังไฟล์ที่มีชื่อที่จัดแจงไว้ล่วงหน้า เมื่อคุณต้องการให้กระบวนการมีอยู่อ่าน pidfile และดูว่ามีกระบวนการที่มี pid นั้นหรือไม่ เมื่อคุณฆ่ากระบวนการลบ pidfile ปัญหาที่สำคัญที่สุดกับ pidfile ที่ไม่ได้สำรองคือถ้ากระบวนการตาย pid อาจถูกนำกลับมาใช้โดยกระบวนการที่ไม่เกี่ยวข้อง อย่างน้อยคุณควรตรวจสอบชื่อกระบวนการหรือกระบวนการที่ปฏิบัติการได้เพื่อให้แน่ใจว่าคุณกำลังพูดคุยกับกระบวนการที่ถูกต้อง หลายตัวแปรยูนิกซ์มีคำสั่งpgrep :pgrep SOMENAME แสดงรายการกระบวนการที่ชื่อมี SOMENAME เป็นสตริงย่อยพร้อมตัวเลือกเพิ่มเติมเพื่อ จำกัด ผู้ใช้เฉพาะต้องมีการจับคู่ที่ตรงกันเพื่อเปลี่ยนความคิดที่เป็นไปได้หลายอย่างของ“ ชื่อกระบวนการ” ที่ใช้ ฯลฯ



1

ตัวเลือกอื่น:

  • pgrep -xq processname
    • ตรงกับอักขระ 15 ตัวแรกใน GNU / Linux เท่านั้น
    • ไม่รวมบรรพบุรุษใน OS X
  • ps -eo comm= | sed 's|.*/||' | grep -xq processname
    • ตรงกับอักขระ 15 ตัวแรกใน GNU / Linux เท่านั้น
    • sed 's|.*/||' ลบส่วน dirname บน OS X

ใน GNU / Linux ps -o commตัดทอนคำสั่งชื่อ 15 ตัวอักษรและpgrepและps -Cเพียงตรงกับ 15 ตัวอักษรแรก

ps -C (ชื่อคำสั่งที่ตรงกัน) ไม่รองรับใน OS X

ใน OS X ps -o commพิมพ์เส้นทางที่แน่นอนของคำสั่งและps -co commพิมพ์ชื่อคำสั่งเท่านั้น ใน GNU ps -o commจะพิมพ์ชื่อคำสั่งเท่านั้นและ-cมีความหมายแตกต่างกัน

pgrep OS X ไม่รวมถึงกระบวนการบรรพบุรุษ (ชอบทุบตีร์มินัลหรือ launchd) -aโดย pgrep GNU -aรวมถึงพวกเขาโดยการเริ่มต้นและจะไม่สนับสนุน

grep -xและpgrep -xอย่าบอกเป็นนัย-Fดังนั้นให้ใช้-Fxถ้าชื่อกระบวนการสามารถมีอักขระ regex


- C ไม่สามารถใช้ได้ใน cygwin ของฉัน :)
n611x007

1

ฉันขอโทษ แต่โซลูชันเหล่านี้ทั้งหมดไม่สนับสนุน contab เนื่องจากบรรทัดคำสั่งเดียวกันจะปรากฏขึ้นสองครั้งในผลลัพธ์ 'ps'

ดังนั้นนี่คือของฉัน:

## Test pour voir si le même script tourne déjà
## Un fichier .pid est utilisé pour stocké le numéro de process
## Si le pid est en train de tourner alors on sort.
lock_file=$0".pid"
[ -r $lock_file ] && read pid <$lock_file
if [ "$pid" -gt 1 ] && [ `ps --no-headers -p "$pid" | wc -l` -gt 0 ] ; then
    echo "WARNING : le process $pid tourne deja : $0"
    ps -edf | grep `basename $0` | grep -v grep
    echo "WARNING : Arrêt de cette instance ($$)."
    exit 7
fi
echo $$ >$lock_file

คุณเสียใจอะไรเกี่ยวกับ contab คืออะไร คุณหมายถึงการตรวจสอบจากภายในcronงานหรือไม่?
Anthon

0

ด้วย Bash

#!/usr/bin/env bash

[[ $# -eq 0 ]] && { echo -e "Usage:\t\t $0 <Process_name>  <Command here>"; exit 1;  }

ifnotrun(){
        local p=$1
        if ! ps -C "$1" -opid=
        then
                cmd=($@)
                echo ${cmd[@]:1}
        else
                echo "Process \"$p\" Already Running.."
                exit 1
        fi

}

ifnotrun $*

หมายเหตุ: - ลบechoหากเอาต์พุตดูเหมือน Ok


0

ฉันจะอธิบายกรณีที่คุณเรียกใช้คำสั่งใน beckgreoud "$!" บันทึก PID ของพื้นหลังครั้งสุดท้าย ดังนั้นคุณสามารถใช้เพื่อค้นหาในตาราง proccess โดยทำตามคำตอบด้านบน:

sleep 4 &
ps -ef | grep -w  $!  ...

คำสั่ง builtin "งาน" - ลองทำสิ่งนี้:

sleep 4&
J=`jobs`
while [ "$J" ]; do
        sleep 1
        jobs # This line flush the jobs' bufer.
        J=`jobs`
done

เกี่ยวกับตัวเลือก "&&"

แทนที่จะ && ใช้การรอคำสั่ง ในตัวอย่างต่อไปนี้ myproc2 จะไม่ทำงานจนกว่า myproc1 จะเสร็จสิ้น:

myproc1 &
wait
myproc2

0

รับสถานะของกระบวนการของคุณ:

ps -lp $(pgrep <YOUR_PROCESS_NAME>) | tail -1 | awk '{print $11}'

อ้างอิง:

D    uninterruptible sleep (usually IO)
R    running or runnable (on run queue)
S    interruptible sleep (waiting for an event to complete)
T    stopped, either by a job control signal or because it is being traced
W    paging (not valid since the 2.6.xx kernel)
X    dead (should never be seen)
Z    defunct ("zombie") process, terminated but not reaped by its parent

ตัวอย่างเช่นฉันใช้เพื่อเล่นแบบมีเงื่อนไขหรือหยุดกระบวนการ sox ของฉันชั่วคราวในเซสชัน tmux:

/usr/local/bin/tmux if-shell -t sox "[ $(ps -lp $(pgrep sox) | tail -1 | awk '{print $11}') == 'T' ]" \
  'send -t sox "fg" Enter' \
  'send -t sox C-z'

-1

คุณสามารถใช้ภายในสคริปต์:

if [ `ps -ef | grep "script.sh" | grep -v grep | wc -l` -gt 1 ] ; then
echo "RUNNING...."
else
echo "NOT RUNNING..."
fi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.