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

时间:2011-11-08 09:58:36

标签: 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

2 个答案:

答案 0 :(得分:15)

只需找到您要等待的进程的进程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

/usr/bin/waitingScript.sh

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

答案 1 :(得分:0)

如果您正在某种容器中运行此程序,则条件为apparently can be caused by a bug in bash that is easier to encounter in a containerized envrionment

从我对the bash source的阅读(特别是在 # based on # https://community.rstudio.com/t/reorder-data-table-with-seleceted-rows-first/4254 library(shiny) library(DT) ui = fluidPage( actionButton("button1", "Randomize"), fluidRow( column(6, h4("Works"), DT::dataTableOutput('table1', width="90%")), column(6, h4("Doesn't Work"), DT::dataTableOutput('table2', width="90%")) ) ) server = function(input, output, session) { my <- reactiveValues(data = iris) output$table1 <- DT::renderDataTable(isolate(my$data)) output$table2 <- DT::renderDataTable({ DT::datatable(isolate(my$data), options = list(lengthChange=FALSE, ordering=FALSE, searching=FALSE, columnDefs=list(list(className='dt-center', targets="_all")), stateSave=TRUE, info=FALSE), class = "nowrap cell-border hover stripe", rownames = FALSE, editable = FALSE ) %>% DT::formatStyle('Sepal.Width', `text-align`="center") }) observeEvent(input$button1, { # calculate new row order row_order <- sample(1:nrow(my$data)) my$data <- my$data[row_order, ] proxy1 <- DT::dataTableProxy('table1') DT::replaceData(proxy1, my$data) proxy2 <- DT::dataTableProxy('table2') DT::replaceData(proxy2, my$data) }) } shinyApp(ui, server) 的{​​{1}}和RECYCLES_PIDS的评论中)看来,他们正在努力优化对后台工作的跟踪,它们使自己容易受到PID别名的影响(新进程可能会掩盖旧进程的状态);为了减轻这种情况,他们会修剪后台进程历史记录(显然是POSIX要求的?)。如果您碰巧希望在经过修剪的过程中CHILD_MAX,则外壳程序将无法在历史记录中找到它,并认为这意味着它永远都不知道(即,它“不是该过程的子项”)外壳”)。