Сценарій оболонки чекає фонової команди


12

Я пишу сценарій, але мені потрібно щось, що я не можу знайти спосіб це зробити ...

Мені потрібно зробити команду у фоновому режимі "command1 &", а потім десь у скрипті мені потрібно дочекатися її завершення, перш ніж я виконаю command2. В основному, мені це потрібно:

ПРИМІТКА: кожна команда працює у певному каталозі! в кінці циклу while моя команда1 створила 4 каталоги, де в кожному запускається певний процес, так що загальна кількість запущених процесів становить 4

a=1

while [$a -lt 4 ]

     . command1
   #Generates 1 Process  

     a= `export $a +1`
done

   #Wait until the 4 process end and then run the command2 

    . command2

Я бачив щось про waitкоманду з номером процесу pid, але це також не працювало.


Ви контролюєте command1? Чи можете ви змінити його, щоб він повертав PID-адреси 4-х процесів?
terdon

Так! я це вже маю :)
Жоао Макао

Я відповідно оновив свою відповідь. Скажіть, чи відповідає вашим очікуванням.
Лоран К.

Цей Q пов'язаний з цим: unix.stackexchange.com/questions/100801/… . Єдина відмінність - вам потрібно отримати PID від фонового процесу. Ви можете використовувати $!змінну, щоб отримати це, передавши її waitкоманді, як я там показав. $!містить останній фоновий PID, а PID $$останнього запущеного процесу.
slm

3
Гаразд, тепер ваш сценарій взагалі не має сенсу. Навколо є синтаксичні помилки та дивацтва. Чи можете ви показати нам власне сценарій? Чому ви шукаєте команди? Чому б просто не виконати їх?
terdon

Відповіді:


22

Ви можете використовувати команду, wait PIDщоб дочекатися закінчення процесу.

Ви також можете отримати PID останньої команди за допомогою $!

У вашому випадку щось подібне спрацювало б:

command1 & #run command1 in background
PID=$! #catch the last PID, here from command1
command2 #run command2 while command1 is running in background
wait $PID #wait for command1, in background, to end
command3 #execute once command1 ended

Після редагування, оскільки у вас є кілька PID-кодів і ви їх знаєте, ви можете зробити це:

command1 & #run command1 in background
PID1=xxxxx
PID2=yyyyy
PID3=xxyyy
PID4=yyxxx
command2 #run command2 while command1 is running in background
wait $PID1 $PID2 $PID3 $PID4 #wait for the four processes of command1, in background, to end
command3 #execute once command1 ended

Після редагування, якщо ви знаєте створений PID (xxxxx, yyyyy, xxyyy, yyxxx), ви можете також скористатись функцією зачекання зі списком PID-кодів, які потрібно чекати (див. Man). Якщо ви не знаєте їх, можливо, ви можете зібрати їх у команду1 (що таке command1? Власний сценарій?)
Лоран C.

Напевно, найкраще переконатися, що вони згруповані правильно. Дивіться мою відповідь щодо ідеї, як це можна зробити.
mikeserv

4

Найчистіше спосіб зробити це буде мати свій comamnd1повернення товару ІКД запущених процесів і використання waitна кожному з них , як було запропоновано @ LaurentC в відповіді .

Інший підхід був би приблизно таким:

## Create a log file
logfile=$(mktemp)

## Run your command and have it print into the log file
## when it's finsihed.
command1 && echo 1 > $logfile &

## Wait for it. The [ ! -s $logfile ] is true while the file is 
## empty. The -s means "check that the file is NOT empty" so ! -s
## means the opposite, check that the file IS empty. So, since
## the command above will print into the file as soon as it's finished
## this loop will run as long as  the previous command si runnning.
while [ ! -s $logfile ]; do sleep 1; done

## continue
command2

Вибачте, але все ще не працює .. Я ще раз вдосконалю своє запитання!
Жоао Макао

0

Якщо ви використовуєте наступний метод, можливо, вам не знадобиться спеціальне "чекати всіх процесів" після циклу час. Цикл чекатиме завершення струму, command1перш ніж він перейде до вершини. Будь ласка, будьте обережні, як і будь-які поради. Зауважте, єдине, що я зробив, це додати & wait $!до кінця вашого command1.

a=1
while [$a -lt 4 ]
     . command1  & wait $!
   #Generates 1 Process  
     a= `export $a +1`
done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.