GNU टाइमआउट के लिए POSIX बराबर?


14

GNU कोरुटिल्स timeoutकमांड कुछ स्क्रिप्टिंग स्थितियों के लिए बेहद आसान है, अगर यह रन करने के लिए तेज है और इसे बहुत लंबा समय लगेगा, तो इसे कमांड के आउटपुट का उपयोग करने की अनुमति देता है।

मैं timeoutकेवल POSIX निर्दिष्ट उपयोगिताओं के उपयोग के मूल व्यवहार को कैसे अनुमानित कर सकता हूं ?


(मैं इसे का एक संयोजन शामिल हो सकता है सोच रहा हूँ wait, sleep, killऔर जो और क्या, लेकिन शायद मैं एक आसान दृष्टिकोण याद कर रहा हूँ जानता है।)


3
शेल स्क्रिप्ट में टाइमिंग देखें , लेकिन मैं इसे डुप्लिकेट नहीं मानता, क्योंकि मैंने प्री-पॉसिक्स सिस्टम में पोर्टेबिलिटी का अनुरोध किया था और मुझे स्टडिन और स्टडआउट को संरक्षित करने की आवश्यकता थी जो पृष्ठभूमि प्रक्रियाओं से जुड़े कुछ समाधानों को नियंत्रित करते हैं।
गिल्स एसओ- बुराई को रोकें '

command & pid=$! ; sleep 5 && kill $pid
पंड्या

1
@ पांड्या एक मामूली दौड़ की स्थिति का परिचय नहीं देता है, जिसमें अगर commandतेजी से खत्म होता है pidतो killकमांड चलने से पहले शुरू होने वाली एक अन्य प्रक्रिया द्वारा पुन: उपयोग किए जाने की एक पतली संभावना है ? मैं नहीं चाहूंगा कि उत्पादन कोड में ....
वाइल्डकार्ड

क्या आप उस अंतर्निहित समस्या के बारे में अधिक बता सकते हैं जिसे आप हल करने की कोशिश कर रहे हैं? क्यों न केवल timeoutकार्यक्रम को संकलित करें और इसका उपयोग करें?
जेम्स यंगमैन

2
@JamesYoungman, मुझे लगता है कि आप पोर्टेबिलिटी के लिए स्क्रिप्ट लिखने से बहुत परिचित नहीं हैं । POSIX- कंप्लेंट (या POSIX- निर्दिष्ट) करने के लिए कुछ करने का तरीका यह बताता है कि यह पोर्टेबल होने का इरादा है। एक द्विआधारी में स्रोत कोड संकलन जोरदार ढंग से पोर्टेबल नहीं है, और, अपनी कंपनी के सुरक्षा नीतियों पर निर्भर करता है, तो आप एक संकलक स्थापित नहीं हो सकता है सब पर एक उत्पादन सर्वर पर।
वाइल्डकार्ड

जवाबों:


2

मेरा दृष्टिकोण यह होगा:

  • पृष्ठभूमि प्रक्रिया 1 के रूप में निष्पादित कमांड

  • पृष्ठभूमि प्रक्रिया 2 के रूप में "वॉचडॉग टाइमर" निष्पादित करें

  • पैरेंट शेल में समाप्ति संकेत को फंसाने के लिए हैंडलर सेट करें

  • दोनों प्रक्रियाओं के पूरा होने की प्रतीक्षा करें। पहले समाप्त होने वाली प्रक्रिया, अभिभावक को समाप्ति संकेत भेजती है।

  • माता-पिता का जाल हैंडलर नौकरी नियंत्रण के माध्यम से दोनों पृष्ठभूमि प्रक्रियाओं को मारता है (उनमें से एक पहले से ही परिभाषा द्वारा समाप्त हो गया है, लेकिन यह मार एक हानिरहित नो-ऑप होगा क्योंकि हम पीआईडी ​​का उपयोग नहीं कर रहे हैं, नीचे देखें)

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

#!/bin/sh

TIMEOUT=$1
COMMAND='sleep 5'

function cleanup {
    echo "SIGTERM trap"
    kill %1 %2
}

trap cleanup SIGTERM

($COMMAND; echo "Command completed"; kill $$) &
(sleep $TIMEOUT; echo "Timeout expired"; kill $$) &

wait
echo "End of execution"

परिणाम TIMEOUT=10(कमांड वॉचडॉग से पहले समाप्त होता है):

$ ./timeout.sh 10
Command completed
SIGTERM trap
End of execution

के लिए परिणाम TIMEOUT=1(कमांड से पहले वॉचडॉग समाप्त होता है):

$ ./timeout.sh 1
Timeout expired
SIGTERM trap
End of execution

के लिए परिणाम TIMEOUT=5(प्रहरी और कमान "लगभग" एक साथ समाप्त):

./tst.sh 5
Timeout expired
Command completed
SIGTERM trap
End of execution

यह POSIX के अनुरूप नहीं है (क) फ़ंक्शन की परिभाषा होनी चाहिए cleanup() { ...; }और (b) नौकरी नियंत्रण एक bash विशेषता है जो POSIX द्वारा निर्दिष्ट नहीं है (हालांकि ksh और अन्य के पास भी है)। हालांकि अच्छी स्क्रिप्ट!
वाइल्डकार्ड

तुम भी साथ बेहतर कर सकते हैं timeout="$1"; shiftऔर (exec "$@"; echo "Command completed"; kill $$)फिर से wordsplitting तर्क सूची के बजाय।
वाइल्डकार्ड 5
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.