sh 和 bash 中 pgrep 的区别

Difference between pgrep in sh and bash

这是一个测试:

$ bash -c "pgrep -f novalidname"
$ sh -c "pgrep -f novalidname"
11202

为什么 pgrepsh 的 运行 时给出输出? (据我所知,我的计算机上没有名为 novalidname 的进程)

这可能是一个时间问题,pgrep 发现自己,因为您使用 -f 发出它并且 novalidname 出现在命令行中。尝试使用 -l 进行确认。

那是一回事(因为延迟发现自己)另见:

$ ps ax | grep novalidname

这里通常也会显示。 (在 Ubuntu 上对我有用。(在 bash 下)

另一件事是 /bin/sh 绑定到什么?

在大多数 Linux 发行版上 /bin/sh 是默认 shell 的软 link,通常实际上是 bash,但可以是任何其他 shell.

导致grep/pgrep显示自身的时间差可能是通过找到一个软link位置(嗯,奇数)或其他shell绑定到[=28来引入的=] 与 bash 的执行略有不同,因此导致进程在 pgrep 中显示所需的延迟。

此外,bash 将首先尝试获取 ~/.bashrc 并加载其历史记录,而 /bin/sh 将执行该操作。在 .bashrc 中可以用另一种方式将 pgrep 定义为别名,这也可能影响差异。

要查看 /bin/sh 点的位置:

$ readlink -e /bin/sh

或者 运行 sh 看看会出现什么。 :D

实际解释:

  1. 不管标志,pgrep 从不 returns 它自己的 PID。

  2. 如果你用一个简单的命令执行bash -c,那么bash将exec这个命令而不是创建一个冗余的子shell来执行它。因此, bash -c "pgrep -f blah" bash 进程替换为 pgrep 进程。如果 pgrep 进程是唯一一个命令行包含 blah 的进程,那么 pgrep 将不会显示任何 PID(按照 1)。

  3. dash不执行上述优化。 (zshksh 可以。)因此,如果在您的系统上,sh 是用 dash 实现的,那么 sh -c "pgrep -f blah" 将导致执行两个进程—— sh 进程和 pgrep 子进程——它们的命令行中都包含 blahpgrep不会报告自己,但会报告其父级。