【问题标题】:Confirmation about pgrep returning itself关于 pgrep 返回自身的确认
【发布时间】:2017-06-08 14:08:34
【问题描述】:

我在这里阅读了几篇关于 pgrep “似乎”返回自身的情况的帖子,即使它永远不会返回。关键似乎是 bash 和 sh 功能之间的区别。除了在我的情况下,我已经确认 sh 确实是 bash 的链接。

  • 我在 SuSE 12 x86_64 上运行
  • /bin/sh 是 bash 的链接
  • /bin/bash 是真正的二进制文件

我有一个像这样调用 pgrep 的 Ruby 脚本:

  cmd="/usr/bin/pgrep -lf \"#{target}\""
  pidList=`#{cmd}`

我需要使用完整的命令行,因为我实际上是在使用一个参数来唯一标识一个特定的“java”进程。

现在,由于一些不相关的愚蠢,我几乎立即对返回的每个 pid 执行 ps -p。有一段时间,这让我很伤心,因为 ps 有时什么也不返回。最终,我能够捕捉到 pid 上的 ps 返回 pgrep 命令的情况。但它是 pgrep 命令本身,而不是 sh -c "pgrep -f blah"

回顾一下:

pgrep 永远不会返回自己。但是 sh 与 bash 的差异可能会导致它显示一个子shell。但是我验证了 sh 是指向 bash 的链接,所以行为上应该没有区别。

我怀疑(并且正在寻找确认)是由于 Ruby 反引号而创建了一个额外的子命令,这就是 pgrep 命令拾取的(仅有时..时间问题?)。

这真的很痛苦,我想确保我实施的修复能够真正解决问题。鉴于我正在使用的代码,我要么去

  1. 在我的命令末尾附加一个| grep -v grep
  2. 在 Ruby 脚本中循环遍历返回的结果时,丢弃任何包含“grep”的结果

我认为 #2 更快,但我仍然很烦我必须过滤掉 pgrep 本身。

我是在正确的轨道上还是你认为还有其他事情在起作用?

感谢您的宝贵时间!

【问题讨论】:

  • bash 被调用为sh 时,它表现为POSIX sh,而不是bash
  • 啊,那将是丢失的拼图!谢谢!

标签: ruby linux bash shell grep


【解决方案1】:

问题不在于 shell 风格:调用 pgrep 的 shell 进程也显示在进程之间(并且在其完整命令中包含搜索到的字符串),所以我们需要像这样过滤掉它:

pgrep -f target | grep -v $$

【讨论】:

    【解决方案2】:

    答案已经在我的问题的 cmets 中,但我想我会用官方答案结束这个问题。

    我丢失的信息是

    当 bash 作为 sh 调用时,它的行为类似于 POSIX sh,而不是 bash。 – Jörg W Mittag 1 月 23 日 23:31

    所以是的,pgrep 表现正常。但是当你通过反引号从 Ruby 脚本调用它时,你仍然需要过滤掉 'pgrep'

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-24
      • 2019-02-09
      相关资源
      最近更新 更多