linux - pgrep {进程名称} | wc -l 返回错误结果
问题描述
我有这个脚本(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。子shell 是一个单独的进程并且具有相同的进程名称test.sh
。因此,现在有两个具有不同 pid 的进程具有进程名称test.sh
。因此pgrep
返回两行。
例如,这可以通过以下方式进行检查:
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
是子shell的495463
pid,是父shell进程的pid。
当你这样做时:
pids=`pgrep 'test.sh'`;
这会输出一个 pid。这是因为 bash 有一个优化,即在特定情况下(例如 no trap
s),当只有一个进程在 shell 中执行时,它会优化并且不调用fork()+exec()
而是调用 just exec
,因为不会有下一个进程运行,所以它可以退出。带有进程名的内部子shelltest.sh
只存在很短的时间,子shell检测到只有一个命令要运行,所以它跳过fork()
,直接执行exec("pgrep")
,变成一个进程名的进程pgrep
。这就是为什么在这种情况下您看不到另一个 pid。
注意:请不要使用反引号`。改为使用$(...)
。
额外:更多子壳!以下
echo "$(echo "$(echo "$(pgrep 'test.sh' | wc -l)")")"
# would output 4
推荐阅读
- javascript - 科尔多瓦应用程序中的警报功能返回 [object, Object]
- excel - 从文件中删除用户功能区
- javascript - 一种告诉 Webpack `import "someFile.js"` 意味着 `import "someFile.ts"` 的方法?
- html - 尽管有 Google Ad Manager 点按区域退出事件,但“缺少点击代码”
- java - 无法在 lambda 表达式中触发异常
- python - ValueError:检查输入时出错:预期dense_1_input的形状为(9,)但得到的数组形状为(1,)
- python - 使用 numpy 对大量数据进行去相关
- python - 在python中将一组字符放入列表中
- c++ - Triangle draws in wrong place before window resize?
- android - Round Corners for both Negative and Positive bars of horizontal bar chart using MpAndroidChart