pgrep {process_name} | wc -l 返回错误结果
pgrep {process_name} | wc -l returning wrong results
我有这个脚本 (test.sh):
#!/bin/bash
echo "pgreg --- start"
pgrep 'test.sh'
echo "pgrep --- end"
process_count=`pgrep 'test.sh' | wc -l`
echo "process_count = $process_count"
pids=`pgrep 'test.sh'`;
fixed_count_process=`echo $pids | wc -w`
echo "pids = $pids";
echo "fixed_count_process = $fixed_count_process"
此脚本的输出总是:
pgreg --- start
56516
pgrep --- end
process_count = 2
pids = 56516
fixed_count_process = 1
我找不到任何合乎逻辑的解释,为什么在将 pgrep
的输出传递给 wc
之前将其存储在变量中会给出正确的结果。有帮助吗?
提前致谢!
因此,首先我们从终端执行 ./test.sh
。所以我们有一个进程名称为 test.sh
.
的进程
process_count=`pgrep 'test.sh' | wc -l`
反引号调用的命令替换运行是一个子shell。 subshell 是一个单独的进程并且具有相同的进程名称test.sh
。所以现在有两个具有不同 pid 的进程,它们的进程名称为 test.sh
。因此 pgrep
returns 两行。
这可以通过以下方式检查:
process_count=$(
ps -e -o pid,comm | grep 'test.sh' >&2
echo BASHPID=$BASHPID $=$$ >&2
pgrep 'test.sh' | wc -l
)
在 stderr 上输出:
495463 test.sh
495466 test.sh
BASHPID=495466 $=495463
495466
是子进程的 pidshell,495463
是父进程的 pid shell。
当你这样做时:
pids=`pgrep 'test.sh'`;
这会输出一个 pid。这是因为 bash 有一个优化,在特定情况下(例如没有 trap
s)当 shell 中只剩下一个进程执行时,它会优化并且不会调用fork()+exec()
相反,它只调用 exec
,因为 运行 没有下一个进程,所以它可以直接退出。进程名称为 test.sh
的内部 subshell 仅存在很短的时间,subshell 检测到只有一个命令到 运行,因此它会跳过 fork()
,就执行了exec("pgrep")
,变成了进程名pgrep
的进程。这就是为什么在这种情况下您看不到另一个 pid 的原因。
注意:请不要使用反引号`。请改用 $(...)
。
额外:更多子shell!以下
echo "$(echo "$(echo "$(pgrep 'test.sh' | wc -l)")")"
# would output 4
我有这个脚本 (test.sh):
#!/bin/bash
echo "pgreg --- start"
pgrep 'test.sh'
echo "pgrep --- end"
process_count=`pgrep 'test.sh' | wc -l`
echo "process_count = $process_count"
pids=`pgrep 'test.sh'`;
fixed_count_process=`echo $pids | wc -w`
echo "pids = $pids";
echo "fixed_count_process = $fixed_count_process"
此脚本的输出总是:
pgreg --- start
56516
pgrep --- end
process_count = 2
pids = 56516
fixed_count_process = 1
我找不到任何合乎逻辑的解释,为什么在将 pgrep
的输出传递给 wc
之前将其存储在变量中会给出正确的结果。有帮助吗?
提前致谢!
因此,首先我们从终端执行 ./test.sh
。所以我们有一个进程名称为 test.sh
.
process_count=`pgrep 'test.sh' | wc -l`
反引号调用的命令替换运行是一个子shell。 subshell 是一个单独的进程并且具有相同的进程名称test.sh
。所以现在有两个具有不同 pid 的进程,它们的进程名称为 test.sh
。因此 pgrep
returns 两行。
这可以通过以下方式检查:
process_count=$(
ps -e -o pid,comm | grep 'test.sh' >&2
echo BASHPID=$BASHPID $=$$ >&2
pgrep 'test.sh' | wc -l
)
在 stderr 上输出:
495463 test.sh
495466 test.sh
BASHPID=495466 $=495463
495466
是子进程的 pidshell,495463
是父进程的 pid shell。
当你这样做时:
pids=`pgrep 'test.sh'`;
这会输出一个 pid。这是因为 bash 有一个优化,在特定情况下(例如没有 trap
s)当 shell 中只剩下一个进程执行时,它会优化并且不会调用fork()+exec()
相反,它只调用 exec
,因为 运行 没有下一个进程,所以它可以直接退出。进程名称为 test.sh
的内部 subshell 仅存在很短的时间,subshell 检测到只有一个命令到 运行,因此它会跳过 fork()
,就执行了exec("pgrep")
,变成了进程名pgrep
的进程。这就是为什么在这种情况下您看不到另一个 pid 的原因。
注意:请不要使用反引号`。请改用 $(...)
。
额外:更多子shell!以下
echo "$(echo "$(echo "$(pgrep 'test.sh' | wc -l)")")"
# would output 4