5 मिनट के लिए कमांड चलाने के लिए एक सरल तरीका क्या है? [डुप्लिकेट]


66

इस सवाल का पहले से ही यहाँ एक जवाब है:

क्या एक आसान तरीका है कि किसी विशिष्ट कमांड (केवल माध्यम से Ctrl-C) को 5 मिनट के लिए स्वचालित रूप से चलाने दिया जाए?

उदाहरण के लिए:

minute-command 5-minutes ping www.google.com

या कोई अन्य आदेश जो स्वयं को समाप्त नहीं करता है।

मैं केवल 5 मिनट ही नहीं, समय-सीमा भी बता सकता हूं।

जवाबों:


67

इस कार्यक्षमता को प्रदान करने वाले कम से कम दो कार्यक्रम हैं:

नाम

timelimit - प्रभावी ढंग से एक प्रक्रिया के पूर्ण निष्पादन समय को सीमित करता है

SYNOPSIS

timelimit [-pq] [-S killsig] [-s warnsig] [-T killtime] [-t warntime] command [arguments ...]

तथा

नाम

timeout - एक समय सीमा के साथ एक कमांड चलाते हैं

SYNOPSIS

timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]

वे निम्नानुसार पैक किए जाते हैं:

$ dlocate `which timeout timelimit`
timelimit: /usr/bin/timelimit
coreutils: /usr/bin/timeout

तुलना:

/-----------------------------+------------+----------------\
|            Feature          |  timelimit |     timeout    |
+=============================+============+================+
|   time to run               | -t time    | first argument |
+-----------------------------+------------+----------------+
|   terminate signal          | -s signal  | -s signal      |
+-----------------------------+------------+----------------+
|   grace period              | -T time    | -k time        |
+-----------------------------+------------+----------------+
|   kill signal               | -S signal  | (note 1)       |
+-----------------------------+------------+----------------+
|   propagate signals         | -p         | (note 2)       |
\-----------------------------+------------+----------------/

टिप्पणियाँ:

  1. timeoutहमेशा SIGKILLअपने अंतिम उपाय संकेत के रूप में उपयोग करता है ।
  2. timeout जब बच्चा प्रोग्राम करता है तो सिग्नल के साथ बाहर निकलने के लिए कोई कार्यक्षमता नहीं होती है।

दो कार्यक्रमों के बाहर निकलने की स्थिति अलग-अलग है, लेकिन यह बड़े करीने से संक्षेप में प्रस्तुत करना कठिन है, इसलिए मेरा सुझाव है कि आप इसके लिए स्वयं मैनुअल पृष्ठों से परामर्श करें।

जैसा कि timeoutडिफ़ॉल्ट रूप से अधिक सिस्टम पर स्थापित है ( coreutilsकई वितरणों में एक मानक पैकेज है), मेरा सुझाव है कि जब तक आपको अतिरिक्त कार्यक्षमता की आवश्यकता न हो, तब तक आप इसका उपयोग करें timelimit


10
आप एक के बजाय दूसरे का उपयोग क्यों करेंगे?
ब्राइस एम। डेम्पसे

2
@ BriceM.Dempsey मेरी स्थानीय मशीन पर, टाइमआउट मौजूद है, लेकिन टाइमलीमिट नहीं है (हालांकि यह रेपो से उपलब्ध है)। इसलिए, यदि उनमें से एक पूर्व-स्थापित आता है ... इसके अलावा, बस विधि हस्ताक्षर को देखकर मैं देख सकता हूं कि वे अलग-अलग चीजें करते हैं, और अलग-अलग उपयोग के मामले हैं।
बेनुबर्ड

ध्यान दें कि कम से कम दो कार्यान्वयन मौजूद हैं timelimit। देखें कि मैं कैसे एक प्रक्रिया को मार सकता हूं और यह सुनिश्चित कर सकता हूं कि पीआईडी ​​का उनके और जीएनयू टाइमआउट के बारे में अधिक जानकारी के लिए पुन: उपयोग नहीं किया गया है
sch

1
@ BriceM.Dempsey timeoutजीएनयू में शामिल है coreutils , timelimitनहीं है। आपने एक या दोनों को स्थापित नहीं किया है। दूसरे के लिए यह सूचित किया जाता है कि टाइमलीमिट एक कमांड निष्पादित करता है और एक दिए गए सिग्नल के साथ दिए गए समय के बाद स्पैन्ड प्रक्रिया को समाप्त करता है। एक "चेतावनी" संकेत पहले भेजा जाता है , फिर, समय समाप्त होने के बाद, एक "मार" संकेत, जिस तरह से init (8) शटडाउन पर संचालित होता है। तो बीच के व्यवहार में भी एक अलग ।
हस्त्तूर

चूंकि GNU कोरुटिल्स को हर GNU / लिनक्स पर प्रीइंस्टॉल्ड किया जाता है, timeoutइसलिए वहां जाने का रास्ता है।
rexkogitans

87

वास्तव में, यह वह है जो timeoutइसके लिए है:

TIMEOUT(1)                          User Commands                         TIMEOUT(1)

NAME
       timeout - run a command with a time limit

SYNOPSIS
       timeout [OPTION] DURATION COMMAND [ARG]...
       timeout [OPTION]

DESCRIPTION
       Start COMMAND, and kill it if still running after DURATION.

lx@lxtp:~$ dpkg -S /usr/bin/timeout
coreutils: /usr/bin/timeout

16

शुद्ध bash, बिना कोर्यूटिल्स के बनाया गया

मैंने पाया कि यह समाधान बाहरी निष्पादन योग्य कॉल के बिना अंतर्निहित कमांड bashपर निर्भर करने में काम करता है । यह उस प्रणाली पर काम करता है जहां अंततः कोर्यूटिल्स भी स्थापित नहीं किए गए हैं [ 1 ]

YourCommand & read -t 300 ;  kill $!                           # 1st version
YourCommand & read -t 300 || kill $!                           # 2nd version 

स्पष्टीकरण : हमेशा की तरह जब आप एक आदेश के साथ पृष्ठभूमि में भेज &, अपने पीआईडी आंतरिक चर में संग्रहीत किया जाता है $!(के आधुनिक संस्करण में मौजूद dash, csh, bash, tcsh, zsh...)।
गोले के बीच वास्तव में क्या फर्क पड़ता है यह अंतर्निहित कमांड read[ 2 ] और विकल्प की उपस्थिति है -t। 1 संस्करण में यदि उपयोगकर्ता सेकंड की निर्दिष्ट राशि से पहले इनपुट की एक पंक्ति को पूरा नहीं करेगा, तो अनुदेश समाप्त हो जाएगा और एक त्रुटि वापसी कोड उत्पन्न होगा।

-TIMEOUT कारण समय से बाहर पढ़ने के लिए और विफलता की वापसी अगर इनपुट की पूरी लाइन TIMEOUT सेकंड के भीतर नहीं पढ़ी जाती है।

दूसरा संस्करण 1 के रूप में काम करता है, लेकिन आप सिर्फ दबाने के लिए हत्या को समाप्त कर सकते हैं enter
वास्तव में या ऑपरेटर केवल स्टेटमेंट को ||निष्पादित करता है killयदि readकमांड शून्य से अलग रिटर्न कोड के साथ बाहर निकलता है, जैसे कि समय समाप्त होने पर। यदि आप enterउस क्षण से पहले दबाते हैं, तो यह 0 पर वापस आ जाएगा और यह आपकी पिछली कमांड को नहीं मारेगा।


Coreutils समाधान [ 1 ]

जब coreutils अपने सिस्टम पर मौजूद हैं और आप समय और संसाधनों को एक बाहरी प्रोग्राम कॉल करने के लिए बचाने के लिए कोई जरूरत नहीं है, timeoutऔर sleepऔर दोनों सही अपने लक्ष्य तक पहुँचने के तरीके हैं।

timeoutका उपयोग timeoutसीधा है।
आखिरकार आप -kपहले फेल होने पर अतिरिक्त किल सिग्नल भेजने के विकल्प का उपयोग करने पर विचार कर सकते हैं ।

timeout 5m YourCommand                                         # 3rd version 

sleep साथ sleepआप अपनी कल्पना का उपयोग करें या कुछ प्रेरणा ले जा सकते हैं [ 3 ] । ध्यान दें कि आप पृष्ठभूमि में या अग्रभूमि में अपनी कमान छोड़ सकते हैं (उदाहरण के लिए topआमतौर पर अग्रभूमि में होना चाहिए)।

YourCommand & sleep 5m; kill $!                                # 4th Background
YourCommand & pid=$! ; (sleep 5m; kill $pid;) &                # 5th Background

bash -c '(sleep 5m; kill $$) & exec YourCommand'               # 6th Foreground
(cmdpid=$BASHPID; (sleep 5m; kill $cmdpid) & exec YourCommand) # 7th Foreground

स्पष्टीकरण

  • 4 वें संस्करण में आप पृष्ठभूमि में निष्पादित YourCommandकरते हैं तो आपका खोल sleep5 minuites के लिए है। जब यह अंतिम पृष्ठभूमि प्रक्रिया समाप्त हो $!जाएगी ( ) को मार दिया जाएगा। तुम अपना खोल बंद करो।
  • 5 वें संस्करण में इसके बजाय आप पृष्ठभूमि में निष्पादित करते हैं YourCommandऔर आप तुरंत उस पीआईडी ​​को चर में संग्रहीत करते हैं $pid। फिर आप पृष्ठभूमि में 5 मिनट की एक झपकी और इसके परिणामस्वरूप कमांड निष्पादित करते हैं जो उस संग्रहीत पीआईडी ​​को मार देगा। चूंकि आपने आदेशों के इस समूह को पृष्ठभूमि में भेजा है इसलिए आप अपने शेल को बंद नहीं करते हैं। आपको पीआईडी ​​को एक चर में संग्रहीत करने की आवश्यकता है क्योंकि $!पृष्ठभूमि में किसी अन्य कार्यक्रम के अंतिम निष्पादन द्वारा मूल्य को अपडेट किया जा सकता है। सरल शब्दों में, आप गलत प्रक्रिया या किसी भी प्रक्रिया को मारने के लिए जोखिम से बचते हैं।
  • 6 वें संस्करण में इसे एक नया बैश शेल कहा जाता है जो 5 मिनट में खुद को आत्महत्या कर लेगा $$, फिर इसे आपके कमांड को निष्पादित किया जाता है जो अग्रभूमि में रहता है।
  • 7 वें संस्करण में, यह एक सबशेल को आमंत्रित करता है ()जो अपने पीआईडी ​​को एक चर ( cmdpid) में संग्रहीत करता है और खुद को पृष्ठभूमि निष्पादन में भेजे गए एक और उपधारा के साथ मारता है, फिर अग्रभूमि में YourCommand चलाएं।

निश्चित रूप से प्रत्येक संस्करण में आप अपनी आवश्यकता के अनुसार किल सिग्नल भेज सकते हैं, डिफ़ॉल्ट रूप से चरम पर kill -9 , केवल तभी उपयोग किया जा सकता है जब वास्तव में आवश्यकता हो।

संदर्भ

  • [ ] कोरुटिल्स
  • [ ] द बैश बिगिनर्स गाइड
  • [ ] बाशफा

2
"नींद के साथ आप अपनी कल्पना का उपयोग कर सकते हैं या कुछ प्रेरणाएं ले सकते हैं [बैश FAQ से लिंक]" +1 #thatsenoughinternetfortoday
joeytwield

11

आपके विशेष मामले के लिए, पिंग्स की किसी विशेष संख्या के बाद pingसमर्थन के अधिकांश कार्यान्वयन -cया --countसमाप्त करने के लिए:

ping -c 300 host.example.com

अधिक सामान्य समाधान के लिए, अन्य उत्तरों को देखें।


7
मुझे ओपी को सिर्फ pingएक ठोस उदाहरण के लिए प्रदान किया गया है। वह हर अलग-अलग प्रोग्राम के लिए केस-बाय-सॉल्यूशन नहीं चाहता है।
user1717828

8

आप इसे इस तरह से एक सरल स्क्रिप्ट के साथ कर सकते हैं:

#!/bin/bash

#
# $1 is the time to let the program run, and $2, $3, ... are the command itself.
#

"${@:2}" &
PID=$!
sleep "${@:1:1}"
kill -2 $PID

(संकेत SIGINT = 2 का उपयोग मतिजा नलिस के सुझाव के अनुसार नीचे टिप्पणी में किया गया है)।

की व्याख्या (असामान्य?) बैश अभिव्यक्ति $@:...: स्थितिगत पैरामीटर, ( $*, $@, "$*", "$@") उदाहरण के लिए, निम्न अतिरिक्त विनिर्देशन स्वीकार करते हैं:

"${@:START:COUNT}"

जिसका अर्थ है: सभी मापदंडों में से, उनमें से COUNT को लें, जो पहले लिया जा रहा है वह STARTth स्थिति में है; यदि COUNT को छोड़ दिया गया है, तो उन सभी को अंत तक ले जाएं, जो कि STARTth स्थिति से शुरू होते हैं। याद रखें कि $0प्रोग्राम का नाम है। यदि START नकारात्मक है, तो अंत से गिनती शुरू करें, और याद रखें कि COUNT नकारात्मक नहीं हो सकता है, इसलिए अंतिम तर्क है "${@:-1}"। इसके अलावा, बस हमेशा दोहरे कोट्स के अंदर स्थितीय मापदंडों को शामिल करें।


1
मैं शायद पहले या आखिरी arg के रूप में समय लेने के लिए स्क्रिप्ट डिजाइन करूँगा, और कमांड के रूप में अन्य सभी args चलाऊंगा। बैश शब्द-फूट डालना $1बहुत स्थूल है। इसके अलावा, आप बस sleep "$1"या कुछ में सकता है countdown
पीटर कॉर्ड्स

1
@PeterCordes आपकी मर्जी के अनुसार किया गया।
MariusMatutiae

पहले arg में समय आपको ऐसा करने देता है time=$1; shift, और फिर आपको स्थिति-संबंधी मापदंडों के लिए सरणी-स्लाइसिंग सिंटैक्स की आवश्यकता नहीं होती है। लेकिन हां, यह बहुत आसान है।
पीटर कॉर्ड्स

1
@PeterCordes सहमत हैं, लेकिन आपने मुझे यह देखने के लिए कहा है कि क्या मुझे ऐसा करने का एक सुरक्षित तरीका पता था और मैं अभी आलसी था, या क्या मैं सिर्फ सादा अज्ञानी था। जबरदस्त हंसी।
MariusMatutiae

जैसा कि पोस्टर ने विशेष रूप से उस कार्यक्रम के बारे में पूछा है जिसके साथ बाधित किया जा सकता है ctrl-c, संभवतः kill -INTइसके बजाय kill -9(या कम से कम -9कुछ सेकंड के बाद ही प्रयास करना बेहतर होगा यदि पहले वाला सुसाइड नहीं किया था - यह प्रोग्राम को साफ-सुथरा निकलने और अस्थायी फ़ाइलों को छोड़ने का मौका देता है इत्यादि के आसपास)
मतिजा नालिस

5

चूंकि आप pingअपने उदाहरण में उल्लेख करते हैं; इस आदेश में कुछ समय की विशिष्ट राशि के बाद रुकने के लिए कुछ विकल्प हैं:

  • w समय सीमा निर्दिष्ट करें कि कितने पैकेट भेजे या प्राप्त किए गए हैं, इसकी परवाह किए बिना पिंग से पहले, सेकंड में, टाइमआउट निर्दिष्ट करें । इस मामले में काउंट पैकेट भेजे जाने के बाद पिंग नहीं रुकता है , यह या तो समय सीमा समाप्त होने तक प्रतीक्षा करता है या जब तक कि काउंट प्रोब का जवाब नहीं दिया जाता है या नेटवर्क से कुछ त्रुटि सूचना के लिए प्रतीक्षा नहीं की जाती है।
  • डब्ल्यू टाइमआउट सेकंड में, प्रतिक्रिया के लिए प्रतीक्षा करने का समय। विकल्प किसी भी प्रतिक्रिया के अभाव में केवल टाइमआउट को प्रभावित करता है, अन्यथा पिंग दो आरटीटी का इंतजार करता है।

-man ping

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