【问题标题】:Difference between pgrep in sh and bashsh 和 bash 中 pgrep 的区别
【发布时间】:2015-10-24 16:52:56
【问题描述】:

这是一个测试:

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

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

【问题讨论】:

  • 请问你最后做了什么。弄清楚这一点对我来说花了相当长的时间。特别是我使用的是内部仅使用 sh 的 popen()。那么您最终是使用 bash 而不是 sh 还是找到了一些更清洁的方法?

标签: bash grep sh


【解决方案1】:

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

【讨论】:

  • 是的,好像是这样。例如,这也给出了输出:bash -c "sleep 1; pgrep -f novalidname"
  • 不是时间问题。这是一个 bash 优化,类似于尾调用优化。
  • 我怀疑在 OP 的系统上/bin/sh 只是指向/bin/bash 的链接。然后呢?
  • @mustaccio:我怀疑你错了:)。我的怀疑是基于问题所揭示的观察到的行为(并且在我使用的系统上完美再现。)你的呢?
【解决方案2】:

这是一回事(因为延迟而发现自己)另请参阅:

$ ps ax | grep novalidname

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

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

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

导致 grep/pgrep 显示自身的时间差异可能是通过查找软链接位置(hm,奇数)或其他一些 shell 绑定到 /bin/sh 来引入的,它的执行与 bash 略有不同,从而导致延迟进程需要在 pgrep 中显示。

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

查看 /bin/sh 指向的地方:

$ readlink -e /bin/sh

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

【讨论】:

    【解决方案3】:

    实际解释:

    1. 无论标志如何,pgrep从不返回它自己的 PID。

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

    【讨论】:

    • "pgrep 从不返回它自己的 PID" -- 你怎么能确定,甚至不知道我们正在处理什么操作系统?
    • @mustaccio:它记录在 pgrep 手册页中。不管操作系统如何,进程很容易获得自己的 PID,因此 pgrep 将其从列表中删除是微不足道的。 pgrep 做出这种保证的事实是它比 grep 输出 ps 更好的工具的原因之一。
    猜你喜欢
    • 2011-08-09
    • 2011-09-03
    • 2022-06-28
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多