शेल स्क्रिप्ट में, मैं (1) बैकग्राउंड में एक कमांड कैसे शुरू कर सकता हूं (2) वेट एक्स सेकंड (3) दूसरी कमांड चलाते हैं जबकि वह कमांड चल रही है?


11

यह वही है जो मुझे होना चाहिए:

  1. पृष्ठभूमि में प्रक्रिया ए शुरू करें
  2. x सेकंड के लिए प्रतीक्षा करें
  3. अग्रभूमि में बी प्रक्रिया शुरू करें

मैं प्रतीक्षा कैसे कर सकता हूं?

मैं देख रहा हूं कि 'नींद' सब कुछ रोक देती है और मैं वास्तव में प्रक्रिया ए के लिए पूरी तरह से 'इंतजार' नहीं करना चाहता। मैंने कुछ समय आधारित छोरों को देखा है लेकिन मैं सोच रहा हूं कि क्या कुछ क्लीनर है।


4
मेरा सुझाव है कि आपने जो पहले से प्रयास किया है उसका एक सरल उदाहरण प्रदान करके आप इस प्रश्न को बढ़ाएँ।
एंडी डाल्टन

10
आपको यह कहां आभास होता है कि sleepप्रक्रिया-ए को रोकती है? क्या आप उस परीक्षण प्रक्रिया को दिखा सकते हैं जिसका आप उपयोग कर रहे हैं, या इसका संकेत दे रहे हैं? तो प्रक्रिया एक है हॉल्टिंग, यह अधिक संभावना है कि यह समय पृष्ठभूमि में चल रहा है और नहीं बल्कि से संबंधित कुछ भी की तुलना में, इस वजह से रुका हो रही टर्मिनल से पढ़ने के लिए कोशिश कर रहा है है sleep
चार्ल्स डफी

3
... अगर ऐसा है , तो टीटीवाई के बजाय process_a </dev/null &इसकी गति को जोड़ देगा /dev/null, और समस्या से बचने के लिए यह पर्याप्त हो सकता है।
चार्ल्स डफी

मेरे अनुभव से नींद केवल वर्तमान प्रक्रिया को अवरुद्ध कर देगी और इस तरह यह प्रक्रिया पहले पृष्ठभूमि में शुरू नहीं हुई और
MADforFUNandHappy

जवाबों:


28

जब तक मैं आपके प्रश्न को गलत नहीं समझ रहा हूँ, यह केवल इस संक्षिप्त स्क्रिप्ट के साथ प्राप्त किया जा सकता है:

#!/bin/bash

process_a &
sleep x
process_b

(और waitयदि आप चाहते हैं कि आपकी स्क्रिप्ट process_aबाहर निकलने से पहले खत्म होने की प्रतीक्षा करे तो अंत में एक अतिरिक्त जोड़ें )।

आप इसे स्क्रिप्ट की आवश्यकता के बिना एक-लाइनर के रूप में भी कर सकते हैं (जैसा कि @BaardKopperud द्वारा सुझाया गया है):

process_a & sleep x ; process_b

6
ध्यान दें कि आपको इसकी आवश्यकता नहीं bashहै, कोई भी शेल आपके सिस्टम सहित करेगा sh, इसलिए आपको अपनी स्क्रिप्ट के लिए बैश पर निर्भरता जोड़ने की आवश्यकता नहीं है।
स्टीफन चेज़लस

4
या बस: process_a और नींद x; process_b
बार्ड कोपरपुड

9

आप बैकग्राउंड में एक प्रक्रिया चलाने के लिए बैकग्राउंड कंट्रोल ऑपरेटर (&) का उपयोग कर सकते हैं और दूसरी प्रक्रिया को चलाने से पहले प्रतीक्षा करने के लिए sleepकमांड , अर्थात:

#!/usr/bin/env bash
# script.sh

command1 &
sleep x
command2

यहां दो आदेशों का एक उदाहरण दिया गया है जो कुछ समय के मुहरबंद संदेशों को प्रिंट करते हैं:

#!/usr/bin/env bash

# Execute a process in the background
echo "$(date) - Running first process in the background..."
for i in {1..1000}; do
    echo "$(date) - I am running in the background";
    sleep 1;
done &> background-process-output.txt &

# Wait for 5 seconds
echo "$(date) - Sleeping..."
sleep 5 

# Execute a second process in the foreground
echo "$(date) - Running second process in the foreground..."
for i in {1..1000}; do
    echo "$(date) - I am running in the foreground";
    sleep 1;
done

यह सत्यापित करने के लिए इसे चलाएं कि यह वांछित व्यवहार प्रदर्शित करता है:

user@host:~$ bash script.sh

Fri Dec  1 13:41:10 CST 2017 - Running first process in the background...
Fri Dec  1 13:41:10 CST 2017 - Sleeping...
Fri Dec  1 13:41:15 CST 2017 - Running second process in the foreground...
Fri Dec  1 13:41:15 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:16 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:17 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:18 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:19 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:20 CST 2017 - I am running in the foreground
...
...
...

2
सवाल " अग्रभूमि में प्रक्रिया बी शुरू करें" से पूछता है ।
स्पार्कवाक

1
@ श्रावक वाह। पूरी तरह से गलत है कि - कोई स्पष्टीकरण नहीं। हेड-अप के लिए धन्यवाद - कोड सही। अपने उपयोगकर्ता नाम से गंभीर उदासीनता, btw।
igal

1
कोई चिंता नहीं! (इसके अलावा यूज़रनेम मूल रूप से इस चैप के लिए एक संदर्भ था , लेकिन मुझे केवल बाद में एहसास हुआ कि यह एक एडिंग्स कैरेक्टर था! और मुझे उन किताबों को फिर से पढ़ना चाहता है ...)
स्पार्कहॉक

5

मुझे @ dr01 का उत्तर पसंद है लेकिन वह बाहर निकलने के कोड की जांच नहीं करता है और इसलिए आपको नहीं पता कि आप सफल थे या नहीं।

यहां एक समाधान है जो एग्जिटकोड की जांच करता है।

#!/bin/bash

# run processes
process_a &
PID1=$!
sleep x
process_b &
PID2=$!
exitcode=0

# check the exitcode for process A
wait $PID1    
if (($? != 0)); then
    echo "ERROR: process_a exited with non-zero exitcode" >&2
    exitcode=$((exitcode+1))
fi

# check the exitcode for process B
wait $PID2
if (($? != 0)); then
    echo "ERROR: process_b exited with non-zero exitcode" >&2
    exitcode=$((exitcode+1))
fi
exit ${exitcode}

आमतौर पर मैं पीआईडी ​​को बैश ऐरे में स्टोर करता हूं और फिर पिड चेकिंग एक लूप के लिए है।


2
आप अपनी स्क्रिप्ट की एक्ज़िट स्थिति में उन एक्ज़िट कोड्स को प्रतिबिंबित करना चाह सकते हैं जैसेA & sleep x; B; ret=$?; wait "$!" || exit "$ret"
स्टीफन चेज़लस

1
@ स्टीफनचैजेलस अच्छा विचार है। मैंने यह सुनिश्चित करने के लिए कोड अपडेट किया कि एक या दोनों विफल होने पर नॉन-जीरो एग्जिटकोड लौटाया जाता है।
ट्रेवर बॉयड स्मिथ

ओपी process_bअग्रभूमि में दौड़ना चाहता है। संभवतः दौड़ते process_aसमय बाहर निकल सकते हैं process_b, लेकिन आप सीधे इसके साथ waitअग्रभूमि process_bकी निकास स्थिति को सामान्य तरीके से एकत्रित करने के बाद भी इसके लिए बाहर निकल सकते हैं और बाहर निकलने की स्थिति प्राप्त कर सकते $?हैं।
पीटर कॉर्ड्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.