एक निश्चित अवधि बीत जाने के बाद रन कमांड?


24

यदि मैं एक लंबी प्रक्रिया निष्पादित कर रहा हूं, तो क्या कोई तरीका है जिससे मैं कुछ समय-आधारित आदेशों को निष्पादित कर सकता हूं?

उदाहरण के लिए, मैं एक बहुत लंबी प्रक्रिया चला रहा हूं जो लगभग 10 मिनट चलती है।

5 मिनट के बाद, मैं एक अलग कमांड चलाना चाहूंगा। चित्रण के लिए, अलग कमांड हो सकती है:echo 5 minutes complete

(नोट: मैं कमांड को पूरा करने की दिशा में प्रगति नहीं करना चाहता, लेकिन केवल निर्दिष्ट अंतराल के बाद निष्पादित कमांड।)

क्या यह संभव है?


1
अधिकांश समय, आप पहले से नहीं जानते हैं कि एक प्रक्रिया में कितना समय लगेगा।
चोराबा

आपका क्या मतलब है "समय-आधारित कमांड"? क्या आप एक प्रगति बार बनाना चाहते हैं? अपने प्रश्न के वर्तमान वाक्यांश के आधार पर, आप केवल लंबे समय तक चलने वाले कमांड को पृष्ठभूमि में रख सकते हैं और फिर सिस्टम घड़ी प्रदर्शित कर सकते हैं। कृपया स्पष्ट करें।
वाइल्डकार्ड

@Wildcard मैंने सवाल में स्पष्ट किया। प्रोग्रेसबार नहीं। यह कुछ अंतराल के बाद कमांड निष्पादित करेगा
अनिकेत भट्टाचार्य

1
"5 मिनट पूरा" गूंजने के लिए एक अजीब बात है। "5 मिनट बीत गए" नहीं? "समय _____" नहीं है? क्या आप केवल यह सुनिश्चित करना चाहते हैं कि समय का कुछ निर्दिष्ट अंतराल उस समय से समाप्त हो गया है जब आपकी लंबी चलने वाली कमांड शुरू की गई थी, इससे पहले कि एक और मनमाना कमांड चलाया जाए? यदि हां, तो बस क्यों नहीं longcommand & sleep 300 && command-to-do-after-five-minutes? (वास्तव में वह वही है जो आप ढूंढ रहे हैं।) ध्यान दें कि आपका स्पष्टीकरण पर्याप्त नहीं था, क्योंकि आपको बल्ले से दो घड़ी प्रगति-बार कार्यान्वयन मिला था।
वाइल्डकार्ड

जवाबों:


29

बस दौडो:

long-command & sleep 300; do-this-after-five-minutes

do-this-after-five-minutesपांच मिनट के बाद चलाने के मिल जाएगा। long-commandपृष्ठभूमि में चल रहा हो जाएगा।


10
मैं आमतौर पर उपयोग करता हूं sleep 5m && foobar, इसलिए यदि मैं अपना दिमाग बदल देता हूं और ^ सी sleep, अगला कमांड नहीं चलता है।
पीटर कॉर्ड्स

@PeterCordes, जब मैंने इसे उदा sleep 3; lsऔर इसके साथ परीक्षण किया ^C, तो दूसरी कमान वैसे भी नहीं चलती है। वास्तव में यकीन नहीं है कि क्यों और शायद यह एक गैर-इंटरैक्टिव शेल में अलग तरह से काम करता है?
वाइल्डकार्ड

1
@PeterCordes काफी नहीं - जब तक कि यह प्रति शेल भिन्न न हो। जब sleep 5m && echoसो रहा है, जब आप निलंबित करते हैं, तो केवल sleepकमांड निलंबित है। बाकी की कमांड लाइन चलती है, लेकिन जब sleepसे सस्पेंड हुआ, तब तक यह सफलतापूर्वक बाहर नहीं निकला और इसके बाद &&का हिस्सा छोड़ दिया गया। सस्पेंड करने की कोशिश करें sleep 5 || echo hello, और helloसीधे दबाने के बाद दिखाएं ^Z
HVD

1
@hvd: हाँ, आप सही हैं, और मैं फिर से गलत हूं जाहिरा तौर पर यह बहुत लंबा हो गया है क्योंकि मैंने तय किया है कि && घेटो के रूप में जाने के लिए रास्ता था at(1), sleep 30m && mplayer something.mp3अलार्म अनुस्मारक जैसे सामान के लिए , या sleep 90m && fgबाद में डिस्क-गहन कमांड को फिर से शुरू करने के लिए । तो वास्तव में, sleep 5m && echo helloअच्छा है क्योंकि निम्नलिखित आदेश को चलाने के बिना ^Zनिलंबित sleepकरता है। यदि आप संपूर्ण कंपाउंड कमांड को निलंबित / फिर से शुरू करने में सक्षम होना चाहते हैं, तो भी सोने से पहले, उपयोग करें ( sleep 2 && echo hello )
पीटर कॉर्ड्स

@hvd: &&मुहावरा आपको पूरी तरह सुनिश्चित करता है कि आप सोने के बाद सही प्रक्रिया को न मारें (क्योंकि आप ^Zकमांड को नहीं चला सकते हैं , बजाय जोखिम के ^C)। यह उपयोग sleep && fgया sleep && bgउपयोग के मामले में उपयोगी है , जब कमांड को फिर से शुरू किया जा रहा है, तो यह कुछ धीमा है।
पीटर कॉर्ड्स

5

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

#!/bin/bash

TEMPFILE="$(mktemp)"
STARTTIME="$(date +%s)"
(./longprocess; rm -f "$TEMPFILE") &
while [ -f "$TEMPFILE" ]; do
    sleep 1s
    NOW="$(date +%s)"
    if (( (NOW-STARTTIME) % 300 == 0 )); then
        echo "$(( (NOW-STARTTIME)/60 )) minute(s) elapsed"
    fi
done
echo "Done!!!"

यह आपके longprocessअंदर निष्पादित करता है sub-shellऔर फिर अस्तित्व के लिए पहले से निर्मित 'लॉक' फ़ाइल की निगरानी करता है।


2
चेक man bashके लिए SECONDS। आप SECONDS=0स्क्रिप्ट की शुरुआत में सेट कर सकते हैं और केवल 300 या अधिक के बराबर या सेट की जांच कर सकते हैं और अपनी स्क्रिप्ट में फिर से SECONDS=$((date +%s))उपयोग dateकरना भूल सकते हैं ...

@ यति, संकेत के लिए धन्यवाद, मुझे वह नहीं पता था।
सर्ज

@yeti, अगर आप उस समय पर भरोसा करना चाहते हैं, जो sleep 1sहमेशा पहले के मुकाबले एक सेकंड बाद हो sleep 1s... तो आप फाल्सहुड के शिकार हो गए हैं कि प्रोग्रामर समय के बारे में विश्वास करते हैं । (हालांकि इस मामले में, आप बस एक हैश मार्क प्रगति बार या कुछ और दिखा सकते हैं।)
वाइल्डकार्ड

@Wildcard ... मैंने बिल्कुल उल्लेख नहीं किया sleep!

@ यति, ठीक तुम हो। टिप के बारे में धन्यवाद SECONDS! :)
वाइल्डकार्ड

4

इसके लिए एक लाइनर है:

( ( sleep $TIMEOUT ; echo "5 minutes complete") & $COMMAND )

आपके मामले में TIMEOUT = 5m और COMMAND लंबी कमांड है।

'सेवा नेटवर्क पुनः आरंभ' के साथ इस पोस्ट टाइमआउट के लिए मेरा उत्तर भी देखें


अग्रभूमि में एक उपखंड लॉन्च करना और फिर कमांड निष्पादित करना अनावश्यक रूप से जटिल लगता है। मैं बाहरी कोष्ठक और निष्पादन को हटा दूंगा।
ग्लेन जैकमैन

1
@glennjackman इस तरह से CTRL + C (उदाहरण के लिए) भेजने की पूरी प्रक्रिया को मुख्य (सबसे बाहरी) सब-शेल को मार सकता है।
coffeMug

1
लेकिन अमल का उपयोग करते हुए, आपके पास अब सबस्क्रिप्शन नहीं है, आपके पास केवल कमांड है। कमांड का जनक स्क्रिप्ट को चलाने वाला शेल होता है जैसे कि आपने सब-उपले का उपयोग नहीं किया हो।
ग्लेन जैकमैन

3
#! /bin/bash

( sleep 4 ) & # <-- The long running process.

seconds=1
while jobs %1 &>/dev/null ; do
    echo $((seconds++)) seconds complete
    sleep 1    
done
echo Done.

jobs %1 एक बार नौकरी% 1 बंद हो जाने पर विफल हो जाती है।

ध्यान दें कि अधिक समय तक, $ सेकंड वास्तविक समय के साथ सिंक से बाहर हो सकते हैं। शुरुआती समय को स्टोर करना और वास्तविक समय के अंतर की गणना करना बेहतर है।

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