等待子进程但得到错误:'pid不是这个shell的子进程'

hen*_*hao 17 linux shell wait

我编写了一个脚本来从HDFS并行获取数据,然后我在for循环中等待这些子进程,但有时它会返回"pid不是这个shell的子代".有时,它运作良好.令人费解.我使用"jobs -l"来显示在后台运行的所有作业.我确信这些pid是shell进程的子进程,我使用"ps aux"来确保这些pid是注释分配给其他进程.这是我的剧本.

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
Run Code Online (Sandbox Code Playgroud)

小智 18

只需找到您要等待的进程的进程ID,并在下面的脚本中用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
Run Code Online (Sandbox Code Playgroud)

/usr/bin/waitingScript.sh

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

  • 不太好,如果每个计算机程序都使用这样的轮询,那将是一件非常糟糕的事:) (5认同)
  • 我将无法获得子进程的退出代码 (2认同)
  • 整洁的。我不敢相信没有标准工具可以在任何地方执行此操作...我制作了一个名为 `waitpid` 的更简单的 shell 脚本,它基本上是这样的:`while [ -e /proc/$1 ]; 做睡眠1; 完成`... (2认同)

jhf*_*ntz 7

如果您在某种容器中运行它,则这种情况显然可能是由 bash 中的错误引起的,该错误在容器化环境中更容易遇到

从我对bash 源代码的阅读来看(特别是参见 周围RECYCLES_PIDSCHILD_MAX中的注释bash-4.2/jobs.c),看起来他们在努力优化对后台作业的跟踪时,使自己容易受到 PID 别名的影响(其中新进程可能会掩盖旧进程的状态) );为了缓解这种情况,他们修剪了后台进程历史记录(显然是按照 POSIX 的规定?)。如果您碰巧想要wait修剪一个进程,则 shell 无法在历史记录中找到它,并假设这意味着它从未知道它(即,它“不是此 shell 的子进程”)。


seh*_*ehe 6

您的 while 循环或 for 循环在子 shell 中运行,这就是为什么您不能等待(父、外)shell 的子级的原因。

编辑这可能发生如果 while 循环或 for 循环实际上是

(a) 在一个{...}区块中 (b) 参与一个吹笛者(例如for....done|somepipe