Collecting process ids of parallel process in bash file

时间:2017-12-08 15:37:19

标签: bash shell pid

Below I have a script that is collecting the process ids of individual commands, and appending them to an array in bash. For some reason as you can see stdout below, the end resulting array just contains one item, the latest id. How can the resulting PROCESS_IDS array at the end of this script contain all four process ids?

PROCESS_IDS=()

function append {
    echo $1
    PROCESS_IDS=("${PROCESS_IDS[@]}" $1)
}

sleep 1 && echo 'one' & append $! &
sleep 5 && echo 'two' & append $! &
sleep 1 && echo 'three' & append $! &
sleep 5 && echo 'four' & append $!
wait

echo "${PROCESS_IDS[@]}"

Here is the stdout:

83873
83875
83879
83882
three
one
four
two
83882

2 个答案:

答案 0 :(得分:3)

不要将append操作本身发送到后台。将& 放在之后的背景内容之前 append就足够了:sleepecho仍然是背景,但append不是。

process_ids=( )
append() { process_ids+=( "$1" ); }       # POSIX-standard function declaration syntax

{ sleep 1 && echo 'one'; } & append "$!"
{ sleep 5 && echo 'two'; } & append "$!"
{ sleep 1 && echo 'three'; } & append "$!"
{ sleep 5 && echo 'four'; } & append "$!"

echo "Background processes:"              # Demonstrate that our array was populated
printf ' - %s\n' "${process_ids[@]}"

wait

答案 1 :(得分:1)

我的猜测是每当你向后台发送一个函数调用时,它都有一个全局变量的副本,所以他们将PID附加到四个独立的副本PROCESS_IDS。这就是每个函数调用发现它为空并在其中存储单个PID的原因。

http://www.gnu.org/software/bash/manual/bashref.html#Lists

  

如果命令由控制操作符'&'终止,则shell在子shell中异步执行命令。这称为在后台执行命令。

如果要收集所有四个函数调用的输出,请让它们写入磁盘并在结尾读取输出:

function append {
    echo $1 | tee /tmp/file.$1
}

sleep 1 && echo 'one' & append $! &
sleep 5 && echo 'two' & append $! &
sleep 1 && echo 'three' & append $! &
sleep 5 && echo 'four' & append $!
wait

cat /tmp/file.*

编辑:这只是一个概念证明 - 无论如何都不要使用文件系统(正如William指出的那样,除非你考虑到唯一性,否则这将是容易出错的和同步)。我只是想说明你需要找到另一种从子壳中获取信息的方法。