Подождите дочернего процесса, но получите ошибку: "pid не является дочерним элементом этой оболочки"
Я пишу script для получения данных из HDFS parrallel, тогда я жду этих дочерних процессов в цикле for, но иногда он возвращает "pid не является дочерним элементом этой оболочки". иногда это работает хорошо. Это так озадачено. Я использую "jobs -l", чтобы показать все задания, выполняемые в фоновом режиме. Я уверен, что эти pid - это дочерний процесс процесса оболочки, и я использую "ps aux", чтобы убедиться, что эти pids отмечены назначением другому процессу. Вот мой script.
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
Ответы
Ответ 1
Просто найдите идентификатор процесса, который вы хотите подождать, и замените его на 12345 ниже script. Дальнейшие изменения могут быть сделаны в соответствии с вашими требованиями.
#!/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/bin/waitingScript.sh
http://iamparv.blogspot.in/2013/10/unix-wait-for-running-process-not-child.html
Ответ 2
Либо цикл while, либо цикл for работает в подоболочке, поэтому вы не можете ждать дочернего элемента (родительской, внешней) оболочки.
Изменить, это может произойти, если цикл while или for на самом деле
(a) в блоке {...}
(b) участие в трубопроводе (например, for....done|somepipe
)
Ответ 3
Если вы выполняете это в каком-то контейнере, это условие может быть вызвано ошибкой в bash, с которой легче столкнуться в контейнеризованной среде.
Из моего прочтения источника bash (в частности, см. Комментарии к RECYCLES_PIDS
и CHILD_MAX
в bash-4.2/jobs.c
) bash-4.2/jobs.c
, что в их усилиях по оптимизации отслеживания фоновых заданий они оставляют себя уязвимыми для псевдонимов PID (где новые процесс может затенить статус старого); чтобы смягчить это, они сокращают свою историю фоновых процессов (очевидно, как предписано POSIX?). Если вам захочется wait
сокращения процесса, оболочка не сможет найти его в истории и предполагает, что это означает, что она никогда не знала об этом (то есть, что она "не является потомком этой оболочки").