【发布时间】:2012-07-17 12:57:27
【问题描述】:
如何从脚本本身中找到 bash 脚本的子进程数?
【问题讨论】:
如何从脚本本身中找到 bash 脚本的子进程数?
【问题讨论】:
要获取 bash 脚本的 PID,您可以使用变量 $$。
然后,要获得它的孩子,你可以运行:
bash_pid=$$
children=`ps -eo ppid | grep -w $bash_pid`
ps 将返回父 PID 列表。然后grep 过滤所有与 bash 脚本的子进程无关的进程。为了得到孩子的数量,你可以这样做:
num_children=`echo $children | wc -w`
实际上,您将获得的数字将减 1,因为 ps 也将是 bash 脚本的子代。如果您不想将 ps 的执行算作孩子,那么您可以通过以下方式解决:
let num_children=num_children-1
更新:为了避免调用grep,可能会使用以下语法(如果已安装的ps版本支持):
num_children=`ps --no-headers -o pid --ppid=$$ | wc -w`
【讨论】:
grep -w $bash_pid 如果 bash pid 是子进程 ID 的子字符串。
grep:ps -o ppid= -p $$(至少对于GNU ps)。
foo=$(sleep 10 | wc -l) 的小脚本。然后我检查了ps,sleep 和wc 都被列为脚本的直接子级(即,两者之间没有新的 shell)。
使用 ps 和 --ppid 选项来选择当前 bash 进程的子进程。
bash_pid=$$
child_count=$(ps -o pid= --ppid $bash_id | wc -l)
let child_count-=1 # If you don't want to count the subshell that computed the answer
(注意:对于--ppid,这需要ps 的Linux 版本。我不知道是否有BSD ps 的等效版本。)
【讨论】:
ps: illegal option -- -。也许您假设的是特定版本的 ps?
您可以评估 shell 内置命令作业,例如:
counter = `jobs | wc -l`
【讨论】:
$() 而不是反引号。
你也可以使用 pgrep:
child_count=$(($(pgrep --parent $$ | wc -l) - 1))
使用pgrep --parent $$ 获取 bash 进程的子进程列表。
然后在输出上使用wc -l 得到行数:$(pgrep --parent $$ | wc -l)
然后减 1(即使pgrep --parent $$ 为空,wc -l 也会报告 1)
【讨论】:
我更喜欢:
num_children=$(pgrep -c -P$$)
它只产生一个进程,您不必计算字数或通过管道中的程序调整 PID 的数量。
例子:
~ $ echo $(pgrep -c -P$$)
0
~ $ sleep 20 &
[1] 26114
~ $ echo $(pgrep -c -P$$)
1
【讨论】:
如果作业计数(而不是 pid 计数)足够,我只提供了一个 bash-only 版本:
job_list=($(jobs -p))
job_count=${#job_list[@]}
【讨论】: