дождитесь дочернего процесса, но получите ошибку: «pid не является дочерним элементом этой оболочки» - PullRequest
14 голосов
/ 08 ноября 2011

Я пишу скрипт для получения данных из HDFS параллельно, затем жду этих дочерних процессов в цикле for, но иногда он возвращает «pid не является дочерним для этой оболочки». иногда это работает хорошо - это так озадачено. Я использую "jobs -l", чтобы показать все задания, запущенные в фоновом режиме. Я уверен, что эти pid являются дочерними процессами процесса оболочки, и я использую «ps aux», чтобы убедиться, что эти pids являются записью, назначенной другому процессу. Вот мой сценарий.

PID=()
FILE=()
let serial=0

while read index_tar
do
        echo $index_tar | grep index > /dev/null 2>&1

        if [[ $? -ne 0 ]]
        then
                continue
        fi

        suffix=`printf '%03d' $serial`
        mkdir input/output_$suffix
        $HADOOP_HOME/bin/hadoop fs -cat $index_tar | tar zxf - -C input/output_$suffix \
                && mv input/output_$suffix/index_* input/output_$suffix/index &

        PID[$serial]=$!
        FILE[$serial]=$index_tar

        let serial++

done < file.list

for((i=0;i<$serial;i++))
do
        wait ${PID[$i]}

        if [[ $? -ne 0 ]]
        then
                LOG "get ${FILE[$i]} failed, PID:${PID[$i]}"
                exit -1
        else
                LOG "get ${FILE[$i]} success, PID:${PID[$i]}"
        fi
done

Ответы [ 3 ]

16 голосов
/ 16 октября 2013

Просто найдите идентификатор процесса, которого вы хотите ждать, и замените его на 12345 в приведенном ниже сценарии. Дальнейшие изменения могут быть сделаны согласно вашему требованию.

#!/bin/sh
PID=12345
while [ -e /proc/$PID ]
do
    echo "Process: $PID is still running" >> /home/parv/waitAndRun.log
    sleep .6
done
echo "Process $PID has finished" >> /home/parv/waitAndRun.log

/ USR / бен / waitingScript.sh

http://iamparv.blogspot.in/2013/10/unix-wait-for-running-process-not-child.html

3 голосов
/ 08 ноября 2011

Либо цикл while, либо цикл for выполняется в подоболочке, поэтому вы не можете ожидать дочернего элемента (родительского, внешнего) оболочки.

Редактировать это может произойти, если цикл while или for фактически равен

(а) в блоке {...} (б) участие в пайпер (например, for....done|somepipe)

0 голосов
/ 04 июля 2019

Если вы запускаете это в каком-то контейнере, условие , очевидно, может быть вызвано ошибкой в ​​bash, с которой легче столкнуться в контейнере .

Отмое чтение источника bash (в частности, см. комментарии вокруг RECYCLES_PIDS и CHILD_MAX в bash-4.2/jobs.c), похоже, что в их усилиях по оптимизации отслеживания фоновых заданий они оставляют себя уязвимыми для PIDалиасинг (когда новый процесс может скрыть статус старого);чтобы смягчить это, они сокращают свою историю фоновых процессов (очевидно, как предписано POSIX?).Если вам захочется wait в сокращенном процессе, оболочка не сможет найти его в истории и предполагает, что это означает, что она никогда не знала об этом (то есть, что она "не является дочерней для этой оболочки")).

...