假设我正在后台运行多个进程实例w1
(来自源代码)(包含无限 while 循环):while1.c
while1.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
命令中)。