वास्तविक उपयोग के लिए, आपको शीर्ष मतदान उत्तर का उपयोग करना चाहिए ।
हालाँकि, मैं कुछ विभिन्न टूटे हुए और अर्ध-काम करने योग्य दृष्टिकोणों का उपयोग करना ps
और उनके पास कई कैविएट पर चर्चा करना चाहता हूं , क्योंकि मैं देखता हूं कि लोग उनका उपयोग करते हैं।
यह उत्तर वास्तव में " शेल में लॉकिंग का उपयोग करने ps
और grep
संभालने के लिए क्यों नहीं ?"
टूटे हुए दृष्टिकोण # 1
सबसे पहले, एक अन्य उत्तर में दिया गया एक दृष्टिकोण, जिसमें इस तथ्य के बावजूद कुछ बदलाव होते हैं कि यह (और कभी नहीं) काम कर सकता है और स्पष्ट रूप से परीक्षण नहीं किया गया है:
running_proc=$(ps -C bash -o pid=,cmd= | grep my_script);
if [[ "$running_proc" != "$$ bash my_script" ]]; do
echo Already locked
exit 6
fi
आइए वाक्यविन्यास त्रुटियों और टूटे हुए ps
तर्कों को ठीक करें और प्राप्त करें:
running_proc=$(ps -C bash -o pid,cmd | grep "$0");
echo "$running_proc"
if [[ "$running_proc" != "$$ bash $0" ]]; then
echo Already locked
exit 6
fi
यह स्क्रिप्ट हमेशा 6 से बाहर होगी , हर बार, चाहे आप इसे कैसे भी चलाएं।
यदि आप इसे चलाते हैं ./myscript
, तो ps
आउटपुट बस होगा 12345 -bash
, जो आवश्यक स्ट्रिंग से मेल नहीं खाता है 12345 bash ./myscript
, ताकि विफल हो जाए।
यदि आप इसे चलाते हैं bash myscript
, तो चीजें अधिक दिलचस्प हो जाती हैं। बाश प्रक्रिया पाइपलाइन चलाने के लिए कांटे , और बच्चा खोल ps
और चलाता है grep
। दोनों मूल खोल और बच्चे खोल में दिखाई देगा ps
उत्पादन, कुछ इस तरह:
25793 bash myscript
25795 bash myscript
यह अपेक्षित आउटपुट नहीं है $$ bash $0
, इसलिए आपकी स्क्रिप्ट बाहर निकल जाएगी।
टूटा हुआ दृष्टिकोण # 2
अब उस उपयोगकर्ता के लिए सभी निष्पक्षता में जो टूटे हुए दृष्टिकोण # 1 को लिखता है, जब मैंने पहली बार ऐसा करने की कोशिश की थी, तो मैंने खुद भी कुछ ऐसा ही किया था:
if otherpids="$(pgrep -f "$0" | grep -vFx "$$")" ; then
echo >&2 "There are other copies of the script running; exiting."
ps >&2 -fq "${otherpids//$'\n'/ }" # -q takes about a tenth the time as -p
exit 1
fi
यह लगभग काम करता है। लेकिन पाइप को चलाने के लिए फोर्किंग का तथ्य यह बंद कर देता है। तो यह हमेशा बाहर निकल जाएगा, भी।
अविश्वसनीय दृष्टिकोण # 3
pids_this_script="$(pgrep -f "$0")"
if not_this_process="$(echo "$pids_this_script" | grep -vFx "$$")"; then
echo >&2 "There are other copies of this script running; exiting."
ps -fq "${not_this_process//$'\n'/ }"
exit 1
fi
यह संस्करण पाइप लाइन में समस्या को टालने से बचता है # 2 सबसे पहले उन सभी पीआईडी को प्राप्त करके जो उनके कमांड लाइन तर्कों में वर्तमान स्क्रिप्ट है, और फिर उस स्क्रिप्ट को फ़िल्टर करके, अलग से, वर्तमान स्क्रिप्ट के पीआईडी को छोड़ना है।
यह काम कर सकता है ... कोई अन्य प्रक्रिया प्रदान करना एक कमांड लाइन से मेल खाता है $0
, और स्क्रिप्ट प्रदान करना हमेशा उसी तरह से कहा जाता है (जैसे कि यदि यह एक रिश्तेदार पथ के साथ कहा जाता है और फिर एक निरपेक्ष पथ है, तो बाद का उदाहरण पूर्व को नोटिस नहीं करेगा। )।
अविश्वसनीय दृष्टिकोण # 4
तो क्या हुआ अगर हम पूरी कमांड लाइन की जाँच करना छोड़ देते हैं, क्योंकि हो सकता है कि वह वास्तव में चलने वाली स्क्रिप्ट का संकेत न दे, और lsof
इस स्क्रिप्ट को खोलने वाली सभी प्रक्रियाओं को खोजने के बजाय जाँच करें ?
ठीक है, हाँ, यह दृष्टिकोण वास्तव में बहुत बुरा नहीं है:
if otherpids="$(lsof -t "$0" | grep -vFx "$$")"; then
echo >&2 "Error: There are other processes that have this script open - most likely other copies of the script running. Exiting to avoid conflicts."
ps >&2 -fq "${otherpids//$'\n'/ }"
exit 1
fi
बेशक, यदि स्क्रिप्ट की एक प्रति चल रही है, तो नया उदाहरण ठीक शुरू हो जाएगा और आपके पास दो प्रतियां चल रही होंगी ।
या यदि रनिंग स्क्रिप्ट को संशोधित किया गया है (उदाहरण के साथ विम के साथ git checkout
), तो स्क्रिप्ट का "नया" संस्करण बिना किसी समस्या के शुरू होगा, क्योंकि विम और git checkout
परिणाम में दोनों एक नई फ़ाइल (एक नया इनोड) के स्थान पर आते हैं। पुराना वाला।
हालांकि, यदि स्क्रिप्ट को कभी भी संशोधित नहीं किया गया है और कभी भी कॉपी नहीं किया गया है, तो यह संस्करण बहुत अच्छा है। कोई दौड़ की स्थिति नहीं है क्योंकि चेक तक पहुँचने से पहले ही स्क्रिप्ट फ़ाइल को खोलना पड़ता है।
यदि किसी अन्य प्रक्रिया में स्क्रिप्ट फ़ाइल खुली है, तो भी झूठी सकारात्मक हो सकती है, लेकिन ध्यान दें कि भले ही यह विम में संपादन के लिए खुला हो, लेकिन विम वास्तव में स्क्रिप्ट फ़ाइल को खुला नहीं रखता है, जिससे झूठी सकारात्मकता उत्पन्न नहीं होगी।
लेकिन याद रखें, यदि स्क्रिप्ट को संपादित या कॉपी किया जा सकता है तो इस दृष्टिकोण का उपयोग न करें क्योंकि आपको झूठी नकारात्मक मिलेंगी अर्थात एक ही बार में कई इंस्टेंसेस चल रहे हैं - इसलिए यह तथ्य कि विम के साथ एडिटिंग किसी भी तरह की झूठी सकारात्मकता नहीं देता है। आप को। मैं, यह उल्लेख है, हालांकि, क्योंकि दृष्टिकोण # 3 करता झूठे सकारात्मक देना (यानी शुरू करने के लिए मना कर दिया) यदि आप स्क्रिप्ट विम के साथ खुला है।
तो क्या करें, फिर?
इस प्रश्न का शीर्ष-मतदान उत्तर एक अच्छा ठोस दृष्टिकोण देता है।
शायद आप एक बेहतर लिख सकते हैं ... लेकिन यदि आप उपरोक्त सभी दृष्टिकोणों के साथ सभी समस्याओं और गुटों को नहीं समझते हैं, तो आप उन सभी को टालने वाली एक लॉकिंग विधि लिखने की संभावना नहीं रखते हैं।
kill
एड को तब टाॅप ट्रैप करना चाहिए , जब एड; और यह अच्छा लगता है कि किसी व्यक्ति को लॉक करने के बजाय केवल उसे छूने से अच्छा है।