Как выполнить команду unix после завершения нескольких фоновых заданий? - PullRequest
0 голосов
/ 24 марта 2019

Мой код c-shell должен выполнить несколько параллельных фоновых заданий перед выполнением некоторых команд Unix. Однако каким-то образом в коде мои фоновые задания никогда не возвращают дескриптор Unix-команд.

т.е.

    $cmd1 | tee $XD/m1.log&
    $cmd2 | tee $XD/m2.log&
    $cmd3 | tee $XD/m3.log&
    $cmd4 | tee $XD/m4.log&

Все 4 упомянутые выше команды генерируют 4 разных файла с именами $L1, $L2, $L3 и $L4 (пример: setenv L1 $XD/div.txt и т. Д.). Мне нужно объединить все эти файлы после удаления из них первой строки, поэтому я использовал следующую логику. Но похоже, что команда sed никогда не выполняется

   wait $!
   echo "Job completed"
   sed -i '1d' $L2
   sed -i '1d' $L3
   sed -i '1d' $L4
   cat $L1 $L2 $L3 $L4 >> $L

Не могли бы вы помочь мне сделать, а затем выполнять пост фоновые задания?

попробовал

if (! -e $L4 ) then 
   if ( -f $L4 ) then 
       wait $!
       echo "Job completed"
       sed -i '1d' $L2
       sed -i '1d' $L3
       sed -i '1d' $L4
       cat $L1 $L2 $L3 $L4 >> $L
   endif
endif

но тоже не помогло.

   $cmd1 | tee $XD/m1.log&
   $cmd2 | tee $XD/m2.log&
   $cmd3 | tee $XD/m3.log&
   $cmd4 | tee $XD/m4.log&

   if (! -e $L4 ) then 
     if ( -f $L4 ) then 
       wait $!
       echo "Job completed"
       sed -i '1d' $L2
       sed -i '1d' $L3
       sed -i '1d' $L4
       cat $L1 $L2 $L3 $L4 >> $L
     endif
   endif

Ожидаемым результатом будет создание файла $L ($XD/final.txt), что произойдет только тогда, когда скрипт вернется во 2-ю половину раздела, содержащего команду sed.

1 Ответ

0 голосов
/ 13 апреля 2019

Краткий ответ, просто используйте:

wait

wait без какого-либо параметра wait будет ожидать всех дочерних процессов.$! является pid последнего запущенного фонового процесса, поэтому wait $! будет ожидать только последнего дочернего процесса.

Длинный ответ, полный скрипт отредактирован:

#!/bin/env tcsh
set cmd1 = 'printf header\nline11\nline12\n'
set cmd2 = 'printf header\nline21\nline22\n'
set cmd3 = 'printf header\nline31\nline32\n'
set cmd4 = 'printf header\nline41\nline42\n'
set XD = '.'
set L = "${XD}/m.log"
set L1 = "${XD}/m1.log"
set L2 = "${XD}/m2.log"
set L3 = "${XD}/m3.log"
set L4 = "${XD}/m4.log"

touch "${L}" "${L1}" "${L2}" "${L3}" "${L4}" || exit (1)
( ${cmd1}; sleep 5 ) | tee "${L1}" &
( ${cmd2}; sleep 2 ) | tee "${L2}" &
( ${cmd3}; sleep 4 ) | tee "${L3}" &
( ${cmd4}; sleep 3 ) | tee "${L4}" &
wait
echo "Job completed"
cat "${L1}" > "${L}"
sed '1d' "${L2}" >> "${L}"
sed '1d' "${L3}" >> "${L}"
sed '1d' "${L4}" >> "${L}" 

exit (0)

Тест:

% ./user3093942.tcsh
[1] 1542 1543
header
line11
line12
[2] 1545 1546
header
line21
line22
[3] 1548 1549
header
line31
line32
[4] 1551 1552
header
line41
line42
[4]  + Done                          ( ${cmd4}; sleep 3 ) | tee ./m4.log
[3]  + Done                          ( ${cmd3}; sleep 4 ) | tee ./m3.log
[2]  + Done                          ( ${cmd2}; sleep 2 ) | tee ./m2.log
[1]  + Done                          ( ${cmd1}; sleep 5 ) | tee ./m1.log
Job completed
% cat ./m.log
header
line11
line12
line21
line22
line31
line32
line41
line42
...