यह देखने के लिए कि क्या कोई प्रक्रिया पहले से ही पृष्ठभूमि में चल रही है (और उसी के आधार पर पुन: निष्पादन छोड़ें) को बैश करें?


11

क्या मैं बैश कमांड लाइन बना सकता हूं जो केवल एक निश्चित कमांड चलाता है अगर प्रक्रिया पहले से ही नहीं चल रही है (पृष्ठभूमि में)?

यदि मैं एक कमांड पहले से चला रहा हूं, तो मैं * कैसे जांचूं?

(इसलिए मैं &&उनके बीच में अगले कमांड को जोड़ सकता हूं इसलिए अगला केवल एक ही निष्पादित होता है यदि पहला सच है)।

*: परीक्षण, निर्धारित, पता लगाना, पता लगाना


3
ps -ef | grep -v grep | grep "process_name" || run_command_here
राहुल पाटिल

1
तुम सिर्फ उपयोग कर सकते हैं @RahulPatil pgrep "process_name"बजायps | grep | grep
भीड़

हम्म, मैं यह भूल जाता हूं ..: D
राहुल पाटिल

1
आप "लॉक" फ़ाइल का उपयोग क्यों नहीं करते हैं, और जब आप दूसरी बार लॉन्च करते हैं, तो यह केवल तभी लॉन्च होगा जब लॉक फ़ाइल गायब हो जाती है।
बिट्सऑफनीक्स

यह देखने का सबसे अच्छा तरीका है कि क्या कोई प्रक्रिया मौजूद है: stackoverflow.com/questions/3043978/…
ट्रेवर बॉयड स्मिथ

जवाबों:


6

डेमोनटूल का उपयोग करें । आप यह svokजांचने के लिए उपयोग कर सकते हैं कि कोई सेवा / डेमॉन / पृष्ठभूमि प्रक्रिया वर्तमान में चल रही है या नहीं।

अन्य तरीकों के लिए देखें:


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

यह मुश्किल हो सकता है, क्योंकि आपके पास एक ही प्रक्रिया के अलग-अलग उदाहरण हो सकते हैं जो स्वतंत्र रूप से रहते हैं। उदाहरण के लिए सर्वर विभिन्न बंदरगाहों, या सेवाओं को विभिन्न उपयोगकर्ताओं के रूप में सुन रहा है। इन उदाहरणों के बीच अंतर करने के लिए, आपको उनमें से प्रत्येक को एक अद्वितीय टैग निर्दिष्ट करने की आवश्यकता है। टैग अक्सर एक फ़ाइल होता है, लेकिन यह सार नाम स्थान, एक टीसीपी पोर्ट, आदि में एक स्थानीय सॉकेट हो सकता है - कोई भी विशिष्ट पहचानकर्ता करेगा। जब टैग एक फ़ाइल होता है, तो यह एक नियमित फ़ाइल हो सकती है जिसमें एक प्रक्रिया आईडी (एक पीडिफ़ाइल), या एक नामांकित पाइप या सॉकेट होता है जिसे फ़ाइल सुन रही है, आदि। आदर्श रूप से, टैग एक संचार समापन बिंदु है जो क्लाइंट को कनेक्ट करने की अनुमति देता है उस प्रक्रिया के लिए।

इन अलग-अलग प्रकार के टैगों में से प्रत्येक में जाँच का एक अलग तरीका होता है कि क्या आप जो उदाहरण मांग रहे हैं वह ऊपर और चल रहा है या नहीं। उदाहरण के लिए, एक स्थानीय फ़ाइल सॉकेट के साथ, इसे कनेक्ट करने का प्रयास करें, और उस सॉकेट पर सुनने की कोई प्रक्रिया नहीं होने पर प्रक्रिया शुरू करें। यदि टैग एक पिडफाइल है, तो जांचें कि क्या उस प्रक्रिया आईडी के साथ कोई प्रक्रिया है, लेकिन सावधान रहें कि यह नाजुक है, क्योंकि यदि प्रक्रिया मर गई है, तो एक असंबंधित प्रक्रिया हो सकती है जिसने अपनी आईडी का पुन: उपयोग किया हो। खबरदार कि अगर दो ग्राहक कम समय सीमा में प्रक्रिया तक पहुंचने की कोशिश करते हैं, तो वे दोनों को पता चल सकता है कि प्रक्रिया मौजूद नहीं है और दोनों इसे शुरू करने का प्रयास करते हैं; इस दौड़ की स्थिति से ठीक से बचाव मुश्किल हो सकता है।

उदाहरणों को प्रबंधित करना तब आसान होता है जब वे सभी एक ही पर्यवेक्षक प्रक्रिया द्वारा शुरू किए जाते हैं, और पर्यवेक्षक प्रक्रिया का पता लगाता है जब उदाहरण मर जाते हैं और तदनुसार प्रतिक्रिया करते हैं। कई सेवा निगरानी कार्यक्रम जो ऐसा कर सकते हैं।

यदि प्रोग्राम एक ज्ञात संचार समापन बिंदु पर प्रतिक्रिया नहीं देता है और यह एक पर्यवेक्षक कार्यक्रम द्वारा प्रबंधित नहीं किया जाता है, तो गरीब आदमी का टैग एक पीडफाइल है: एक फाइल जिसमें प्रक्रिया आईडी है। जब आप प्रक्रिया शुरू करते हैं, तो एक prearranged नाम के साथ फ़ाइल को pid ​​लिखें। जब आपको अस्तित्व की प्रक्रिया की आवश्यकता होती है, तो पीडफाइल पढ़ें और देखें कि क्या उस पिड के साथ कोई प्रक्रिया है। जब आप प्रक्रिया को मारते हैं, तो पिडफाइल मिटा दें। एक अनसुनी पीडिफ़ाइल के साथ सबसे अधिक मुख्य समस्या यह है कि यदि प्रक्रिया मर जाती है, तो इसका पीआईडी ​​कुछ असंबंधित प्रक्रिया द्वारा पुन: उपयोग किया जा सकता है। आपको कम से कम प्रक्रिया नाम या प्रक्रिया निष्पादन योग्य की जांच करनी चाहिए ताकि यह सुनिश्चित हो सके कि आप सही प्रक्रिया से बात कर रहे हैं। कई यूनिक्स वेरिएंट में एक pgrep कमांड है:pgrep SOMENAME उन प्रक्रियाओं को सूचीबद्ध करता है जिनके नाम में एक विकल्प के रूप में SOMENAME होता है, एक विशेष उपयोगकर्ता तक सीमित करने के लिए अतिरिक्त विकल्पों के साथ, सटीक मिलान की आवश्यकता होती है, जो कि "प्रक्रिया नाम" के कई संभावित धारणाओं को बदलने के लिए उपयोग किया जाता है, आदि।


1

आप इस दृष्टिकोण का उपयोग कर सकते हैं:

if [[ -z $(ps -C appname -opid=) ]]; then
    appname && secondapp
fi

1

अन्य विकल्प:

  • pgrep -xq processname
    • केवल GNU / Linux में पहले 15 अक्षरों से मेल खाता है
    • ओएस एक्स पर पूर्वजों को शामिल नहीं करता है
  • ps -eo comm= | sed 's|.*/||' | grep -xq processname
    • केवल GNU / Linux में पहले 15 अक्षरों से मेल खाता है
    • sed 's|.*/||' OS X पर dirname भागों को हटाता है

GNU / Linux में ps -o comm15 वर्णों के नाम ट्रंकटेट करते हैं pgrepऔर ps -Cकेवल पहले 15 वर्णों से मेल खाते हैं।

ps -C (मैच कमांड नाम) OS X पर समर्थित नहीं है।

OS X ps -o commमें कमांड के निरपेक्ष पथों को प्रिंट करता है और ps -co commकेवल कमांड नामों को प्रिंट करता है। GNU में ps -o commकेवल कमांड नामों को प्रिंट करता है और -cइसका एक अलग अर्थ है।

OS X के pgrep में बिना पूर्वजों की प्रक्रिया (जैसे बैश, टर्मिनल या लॉन्च) शामिल नहीं है -a। GNU के pgrep में उन्हें डिफ़ॉल्ट रूप से शामिल किया गया है और यह समर्थन नहीं करता है -a

grep -xऔर pgrep -xइसका मतलब यह नहीं है -F, तो उपयोग -Fxअगर प्रक्रिया नाम regex अक्षर हो सकते हैं।


-C मेरे
साइबर

1

मुझे क्षमा करें, लेकिन ये सभी समाधान कॉन्टैब का समर्थन नहीं करते हैं क्योंकि एक ही कमांड लाइन 'पीएस' परिणाम में दो बार दिखाई देगी।

तो यहाँ मेरा है:

## 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

आप किस बारे में क्षमा चाहते हैं? कबाब क्या है? क्या आपका मतलब cronनौकरी से जाँच करना है?
एंथन

0

बैश के साथ

#!/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यदि आउटपुट ठीक लगे तो निकालें ।


0

मैं उस मामले की व्याख्या करूंगा जहां आप कमांड को beggreoud में चलाते हैं। "$!" अंतिम पृष्ठभूमि के पीआईडी ​​को सुरक्षित रखें। तो, आप इसका उपयोग ऊपर दिए गए उत्तरों के बाद सफल तालिकाओं में खोजने के लिए कर सकते हैं:

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

बिलियन कमांड "जॉब" - यह प्रयास करें:

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

उदाहरण के लिए, मैंने इसे एक tmux सत्र पर अपनी sox प्रक्रिया को सशर्त रूप से खेलने या रोकने के लिए उपयोग किया है:

/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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.