获取脚本中进程的多个实例的 pid 并使用它们

获取脚本中进程的多个实例的 pid 并使用它们

假设我正在后台运行多个进程实例w1(来自源代码)(包含无限 while 循环):while1.cwhile1.c

gcc while1.c -o w1
./w1&
./w1&
./w1&
./w1&

现在我想获取每个实例的PID。为此,我正在这样做:

var=$(/bin/ps r -o pid,cmd|grep "w1"| grep -v "grep"|awk '{print $1}')

w1这将存储in的所有实例的 PID $var
所以,如果我这样做:

echo $var

它将打印出 的所有实例的 PID w1

但我想访问单独的 PID,即:

echo ${var[0]}
echo ${var[1]}

等等(比如数组)。我怎样才能做到这一点?

PS:echo ${var[0]}正在打印所有 PID,而echo ${var[1]}echo ${var[2]}等等,则不打印任何内容(即输出的空白行)。

答案1

启动进程时保存 PID:

pids=()

./w1 & pids+=( "$!" )
./w1 & pids+=( "$!" )
./w1 & pids+=( "$!" )
./w1 & pids+=( "$!" )

(假设 shell 具有bash兼容的数组语法)

现在您在数组中拥有了 PID ,并且可以通过、等pids方式访问它们。"${pids[0]}""${pids[1]}"

如果您使用普通/bin/sh

set --

./w1 & set -- "$@" "$!"
./w1 & set -- "$@" "$!"
./w1 & set -- "$@" "$!"
./w1 & set -- "$@" "$!"

现在您的 PID 已在列表中,并且可以通过、等"$@"方式访问它们。"$1""$2"

该特殊值"$!"将是最近启动的后台命令的PID。

答案2

如果您正在运行 bash,则可以使用jobs -l,它会列出后台作业及其 PID。例如,以下命令会将所有匹配的作业的 PID 存储./w1到 array 中pids

pids=( $(jobs -l | awk '/\.\/w1/ {print $2}') )

在其他 shell 中,您可以用来ps --ppid $$列出以当前 shell 作为父级的所有作业:

pids=( $(ps --ppid $$ -o pid,cmd -h | awk '/\.\/w1/ {print $1}') )

注意:据我所知,这不是可移植的 - 它只能ps在 Linuxprocps软件包中使用。其他版本ps没有相同的选项。

使用 FreeBSD ps,您可以执行类似的操作(在 bash 或 ksh 或其他支持数组的 shell 中):

pids=( $(ps -j | awk -v ppid=$$ '$3==ppid && /\.\/w1/ {print $2}') )

如果你有空pgrep的话,你可以使用:

pids=( $(pgrep -P $$ w1) )

在所有变体中,我都会检查后台进程是否匹配./w1- 如果您确定该 PPID 永远不会运行任何其他子进程或后台进程,您可以在脚本中跳过该测试awk(并且只需要输出-o pid在第二个变体的ps命令中)。

相关内容