Как получить статус завершения работы с несколькими дочерними процессами, независимо от того, завершился ли он успешно или в сценарии оболочки linux - PullRequest
0 голосов
/ 03 февраля 2020

Как можно вернуть или получить статус выхода дочернего процесса по отдельности.

вот дочерний процесс

process()
{
    rem=$(( $PID % 2 ))

    if [ $rem -eq 0 ]
    then
        echo "Number is even $PID"
        exit 0
    else
        echo "Number is odd $PID"
        exit 1
    fi

  echo "fred $return"
  exit $rem
}

for i in {1..100}; do
   process $i &
   PID="$!"
   echo "$PID:$file" 
   PID_LIST+="$PID "
done

for process in ${PID_LIST[@]};do
    echo "current_PID=$process"
   wait $process
   exit_status=$?
   echo "$process  => $exit_status"
done

echo " The END"

что я ожидаю, так это то, что каждое выходное состояние четного числа должно быть 0 и статус выхода нечетного числа должен быть 1. но вышеприведенный скрипт выдает следующий вывод, где у нескольких четных номеров есть статус выхода 1, а у нескольких нечетных номеров есть статус выхода 0. Может кто-нибудь меня поправить.

16687:
16688:
/home/nzv1dtr/sample_file.sh: line 3: % 2 : syntax error: operand expected (error token is "% 2 ")
16689:
Number is odd 16687
16690:
Number is even 16688
16691:
Number is odd 16689
current_PID=16687
16687  => 1
current_PID=16688
16688  => 1
current_PID=16689
Number is even 16690
16689  => 0
current_PID=16690
16690  => 1
current_PID=16691
16691  => 0

1 Ответ

1 голос
/ 03 февраля 2020

Здесь происходит немного больше. По сути, вы на правильном пути, wait может собирать и сообщать о статусе возвращения ребенка, например:

for i in {0..20}; do
        if [[ $((i % 2)) -eq 1 ]]; then
                /bin/true &
        else
                /bin/false &
        fi
        a[${i}]=$!
done

for i in ${a[@]}; do
        wait ${i}; echo "PID(${i}) returned: $?"
done

Почему вы не видите то же самое?

Ну, для начала, process - это (на самом деле) не процесс, а функция (следовательно, как уже упоминалось в комментарии, exit не является правильным способом его завершения, если он вызывается в сценарии, он завершает весь сценарий, а не просто функция). Это действительно процесс, но как часть этого. Shell создаст новую подоболочку и запустит вашу функцию (следовательно, выход не смертелен для внешнего скрипта). Статус, в котором находилась ваша оболочка в момент ее появления, очень важен.

Вы также сравниваете с ${PID}, который на самом деле является PID последней подоболочки, и для первого вызова выдает ошибку. Вы, вероятно, хотели поискать $$, за исключением того, что приведенный выше абзац будет означать, что все функции (вложенные оболочки) будут использовать одно и то же значение (родительского процесса).

Оснащен этой информацией, минимальный изменение в вашем сценарии - использовать $$ в функции process, экспортировать функцию, чтобы мы могли использовать ее в новом экземпляре оболочки, мы fork, мы отслеживаем PID этой новой оболочки:

process()
{
    rem=$(( $$ % 2 ))
...
}

export -f process
for i in {1..100}; do
   bash -c "process" $i &
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...