पहले से चल रहे एक के बाद एक कमांड कैसे चलाएं, मौजूदा एक खत्म?


32

यदि मैं एक स्क्रिप्ट शुरू करता हूं, जो लंबे समय तक चलने वाली है, तो मैंने स्क्रिप्ट शुरू करने के बाद अनिवार्य रूप से इसका एहसास किया है, और काश एक बार इसे खत्म करने के बाद मुझे किसी तरह का अलर्ट करने का एक तरीका मिल जाता।

इसलिए, उदाहरण के लिए, अगर मैं दौड़ता हूं:

really_long_script.sh

और एंटर दबाएं ... एक बार खत्म होने के बाद मैं दूसरी कमांड कैसे चला सकता हूं?

जवाबों:


45

आप कई आदेशों को अलग कर सकते हैं ;, इसलिए उन्हें क्रमिक रूप से निष्पादित किया जाता है, उदाहरण के लिए:

really_long_script.sh ; echo Finished

यदि आप अगले प्रोग्राम को केवल तभी निष्पादित करना चाहते हैं यदि स्क्रिप्ट रिटर्न-कोड 0 के साथ समाप्त हो गई है (जिसका आमतौर पर मतलब है कि इसे सही तरीके से निष्पादित किया गया है), तो:

really_long_script.sh && echo OK

यदि आप इसके विपरीत चाहते हैं (यानी केवल जारी रखें यदि वर्तमान कमांड विफल हो गई है), की तुलना में:

really_long_script.sh || echo FAILED

आप अपनी स्क्रिप्ट को बैकग्राउंड में चला सकते हैं (लेकिन सावधान रहें, स्क्रिप्ट आउटपुट ( stdoutऔर stderr) तब तक आपके टर्मिनल पर जाना जारी रहेगा, जब तक आप इसे कहीं रीडायरेक्ट नहीं करते), और फिर इसके waitलिए:

really_long_script.sh &
dosomethingelse
wait; echo Finished

यदि आपने पहले ही स्क्रिप्ट चला ली है, तो आप इसे स्थगित कर सकते हैं Ctrl-Z, और फिर कुछ इस तरह निष्पादित कर सकते हैं:

fg ; echo Finished

जहाँ fgनिलंबित प्रक्रिया को अग्रभूमि में लाया जाता है ( bgइसे पृष्ठभूमि में चलाया जाएगा, बहुत शुरुआत के साथ जैसे &)


@mlissner ने इस केस को कवर करने के लिए मेरे जवाब का विस्तार किया
अलैंड

8
चूंकि fgयह जिस नौकरी को फिर से शुरू करता है, उसका मूल्य लौटाता है, fg && echo Finishedयदि आप यह सुनिश्चित करना चाहते हैं कि आप दूसरी कमांड को निष्पादित करने से पहले कमांड को सफल करना चाहते हैं या नहीं।
पलसीम

13

आप बैश के जॉब कंट्रोल का भी इस्तेमाल कर सकते हैं। अगर आपने शुरू किया

$ really_long_script.sh

फिर इसे निलंबित करने के लिए ctrl + z दबाएं:

^Z
[1]+  Stopped                 really_long_script.sh
$ bg

पृष्ठभूमि में कार्य को पुनः आरंभ करने के लिए (जैसे कि इसे इसके साथ शुरू किया गया हो really_long_script.sh &)। फिर आप इस पृष्ठभूमि की नौकरी के लिए इंतजार कर सकते हैं

$ wait N && echo "Successfully completed"

जहां N जॉब आईडी है (शायद 1 यदि आपने कोई अन्य बैकग्राउंड जॉब नहीं चलाया है) जो ऊपर भी प्रदर्शित की गई [1]है।


11

यदि प्रक्रिया वर्तमान tty पर नहीं चलती है, तो यह प्रयास करें:

watch -g ps -opid -p <pid>; mycommand

2
मुझे इसके रचनात्मक उपयोग से प्यार है watch। सुपर शॉर्ट जवाब और एक घड़ी का उपयोग करने का एक नया उपयोगी तरीका सीखता है
पियोट्र सीज़ापला

2

यह पता चला है कि यह कठिन नहीं है: आप बस अगले कमांड को विंडो में टाइप कर सकते हैं, जबकि मौजूदा एक चलता है, एंटर दबाएं, और जब पहला खत्म हो जाए, तो दूसरा कमांड अपने आप चल जाएगा।

मुझे लगता है कि वहाँ और अधिक सुंदर तरीके हैं, लेकिन यह काम करने लगता है।

यह जोड़ने के लिए कि यदि आप कमांड खत्म होने के बाद अलर्ट चलाना चाहते हैं, तो आप इन एलियास को .bashrc में बना सकते हैं, फिर alertइसे चलाते समय चलाएं :

 alias alert_helper='history|tail -n1|sed -e "s/^\s*[0-9]\+\s*//" -e "s/;\s*alert$//"'
 alias alert='notify-send -i gnome-terminal "Finished Terminal Job" "[$?] $(alert_helper)"'

7
जब तक कि रनिंग स्क्रिप्ट एक बिंदु पर इनपुट की उम्मीद करती है।
डैनियल बेक

@ डैनियल - हाँ ... यह एक समस्या है। गोली मार।
6

1

कुछ समय पहले मैंने एक और प्रक्रिया के अंत की प्रतीक्षा करने के लिए एक पटकथा लिखी है। NOISE_CMDकुछ ऐसा हो सकता है notify-send ..., जिसे देखते हुए DISPLAYसही तरीके से सेट किया गया हो।

#!/bin/bash

NOISE_CMD="/usr/bin/mplayer -really-quiet $HOME/sfx/alarm-clock.mp3"

function usage() {
    echo "Usage: $(basename "$0") [ PROCESS_NAME [ PGREP_ARGS... ] ]"
    echo "Helpful arguments to pgrep are: -f -n -o -x"
}

if [ "$#" -gt 0 ] ; then
    PATTERN="$1"
    shift
    PIDS="$(pgrep "$PATTERN" "$@")"

    if [ -z "$PIDS" ] ; then
        echo "No process matching pattern \"$PATTERN\" found."
        exit
    fi

    echo "Waiting for:"
    pgrep -l "$PATTERN" "$@"

    for PID in $PIDS ; do
        while [ -d "/proc/$PID" ] ; do
            sleep 1
        done
    done
fi

exec $NOISE_CMD

बिना किसी अड़चन के, बस तुरंत कुछ शोर करें। यह व्यवहारकर्ता सुविधा के लिए कुछ इस तरह की अनुमति देता है (आप नीचे स्क्रिप्ट कहते हैं alarm.sh):

apt-get upgrade ; ~/bin/alarm.sh

बेशक आप इस तरह की स्क्रिप्ट के साथ कई मजेदार चीजें कर सकते हैं, जैसे कि एक उदाहरण के लिए alarm.shप्रतीक्षा का उदाहरण देना alarm.sh, जो किसी अन्य कमांड के लिए इंतजार कर रहा है। या उपयोगकर्ता द्वारा लॉग इन किए गए किसी अन्य के कुछ कार्य के ठीक बाद एक कमांड निष्पादित करना ...>: D

यदि आप निर्भरता से बचना चाहते हैं pgrepऔर प्रक्रिया को देखने के लिए स्वीकार करना चाहते हैं, तो उपरोक्त स्क्रिप्ट का एक पूर्व संस्करण दिलचस्प हो सकता है :

#!/bin/bash

if [ "$#" -lt 2 -o ! -d "/proc/$1" ] ; then
  echo "Usage: $(basename "$0") PID COMMAND [ ARGUMENTS... ]"
  exit
fi

while [ -d "/proc/$1" ] ; do
  sleep 1
done

shift
exec "$@"

थोड़ी-सी ऑफ-टॉपिक, लेकिन समान स्थितियों में उपयोगी: एक में रुचि हो सकती है reptyr, एक उपकरण जो कुछ (माता-पिता) शेल से एक प्रक्रिया को "चुराता है" और इसे वर्तमान शेल से चलाता है। मैंने इसी तरह के कार्यान्वयन की कोशिश की है और reptyrमेरे उद्देश्यों के लिए सबसे सुंदर और सबसे विश्वसनीय है।

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