【问题标题】:ps command in linuxlinux中的ps命令
【发布时间】:2017-01-11 18:01:56
【问题描述】:

我是类 unix 的新手。我遇到了一个奇怪的问题,我真的无法通过搜索找到答案。

#!/bin/bash
me=`basename "$0"`
echo $(ps -e | grep "$me" | wc -l)
ps -e | grep "$me" | wc -l

执行该 bash 脚本后,echo 显示 2,而 ps 仅显示 1,这正是我想要的。这怎么可能发生?为什么 echo 显示了一个额外的进程?

【问题讨论】:

  • $() 创建一个子shell——你的shell的一个分叉副本。因此,当您在运行 echo $(ps -e | grep "$me" | wc -l) 时,实际上还有更多进程正在运行与您的表达式匹配。
  • 也就是说,通过ps 搜索是绝对不好的做法,不应该用于任何类型的自动化使用。虽然有诸如 pgrep 之类的工具可以解决一些注意事项,但如果您的目的是确定程序是否已经在运行,那么还有更好的方法来做到这一点。
  • 欢迎来到 StackOverflow!请阅读用户指南,了解如何在发布问题之前提出一个好问题 (stackoverflow.com/help/how-to-ask) 谢谢

标签: linux bash echo ps


【解决方案1】:

正如查尔斯·达菲指出的那样,$() creates a subshell。这回答了我的问题。显然我还有很多东西要学。感谢大家的帮助。

【讨论】:

    【解决方案2】:

    正如赛勒斯的评论所指出的那样;这个脚本:

    me=$(basename $0)
    ps -ef |grep $me
    

    当使用“./ps.sh”启动时,打印:

    auser@pc:/tmp$ ./ps.sh
    auser     4425  4422  0 08:42 pts/3    00:00:00 grep ps.sh
    auser@pc:/tmp$
    

    这里不涉及子shell,ps(1) 列出的是grep(1) 本身。以“bash ps.sh”输出启动的相同脚本:

    auser     4426  3946  0 08:44 pts/3    00:00:00 bash ps.sh
    auser     4429  4426  0 08:44 pts/3    00:00:00 grep ps.sh
    

    这是 OP 得到的结果,即使没有子shell。更明确:

    auser@pc:/tmp$ ps -ef |grep grep
    auser     4467  3946  0 08:49 pts/3    00:00:00 grep grep
    

    【讨论】:

      【解决方案3】:

      虽然您正在使用 $() 创建子 shell,但您可以使用 grep -v grep 将其 grep。

      所以:

      $(ps -e | grep "$me" | grep -v grep | wc -l)
      

      这将返回 1 而不是 2

      【讨论】:

        猜你喜欢
        • 2015-05-24
        • 1970-01-01
        • 1970-01-01
        • 2014-02-04
        • 1970-01-01
        • 2013-01-04
        • 1970-01-01
        • 2022-10-21
        • 2020-09-03
        相关资源
        最近更新 更多