代码之家  ›  专栏  ›  技术社区  ›  Mike

if语句的计算结果始终为true

  •  7
  • Mike  · 技术社区  · 15 年前

    不管进程是启动还是停止,这个脚本总是返回“running”有什么原因吗?

    if ps ax | grep -v grep | grep "processName" > /dev/null
    then
       echo $"running"
    else
       echo $"not running"
    fi
    

    非常感谢你

    更新: 我添加了一个完整的脚本示例,可能其他地方出错了。

    case "$1" in
      start)
        # Start daemons.
    
        echo -n $"Starting daemon: "
        ;;
    
      stop)
        # Stop daemons.
        echo -n $"Shutting down: "
        echo
        ;;
      status)
        pgrep -f "ProcessName" > /dev/null
        if [ $? -eq 0 ]; then
            echo $"ProcessName is running"
        else
            echo $"ProcessName is not running"
        fi
        ;;
      restart)
        $0 stop
        $0 start
        ;;
    
      *)
        echo $"Usage: $0 {start|stop|status|restart}"
        exit 1
    esac
    

    更新2:

    [user@dev init.d]# pgrep -f "MyProcess" > /dev/null
    [user@dev init.d]# echo $?
    0
    [user@dev init.d]# service MyProcess stop
    Shutting down MyProcess: Terminated
    [user@dev init.d]# pgrep -f "MyProcess" > /dev/null
    [user@dev init.d]# echo $?
    1
    

    但是 if [ $? -eq 0 ]; then 似乎一直都是真的

    4 回复  |  直到 12 年前
        1
  •  16
  •   Shawn Chin    15 年前

    试试这个:

    ps aux | grep -q "[p]rocessName"
    if [ $? -eq 0 ]; then
        echo "running"
    else
        echo "not running"
    fi
    

    processname第一个字母周围的括号表示不需要“grep-v grep”,而-q表示不需要管道到/dev/null

    $?给出上一个执行命令的返回代码。因此,如果它是0,测试将表明“grep”是否找到了它要查找的内容。

    更新

    如果您的进程名真的很短(比如说“cup”),那么您可能会得到一个误报,因为它也可能与其他进程匹配(比如说“cupsd”)。你可以通过让grep匹配整个单词来克服这个问题-添加“-w”标志。

    并不是说这项技术并不完美。您可能会在用户名/日期字段中找到匹配的条目。如果发生这种情况,在做grep之前,查找“man ps”,并对打印出来的内容进行更多的选择。或者,使用awk对输出进行预筛选,以仅提取显示进程/cmd名称的列。例如:

    ps aux | awk '{print $11}' | grep -q -w "[p]rocessName"
    if [ $? -eq 0 ]; then
        echo "running"
    else
        echo "not running"
    fi
    

    更新2

    您也可以使用下面答案中建议的pgrep。

    对于非常短的进程名,您可能需要在进程名前后指定单词边界(\b),以防止过度匹配(如上所述)。

    pgrep "\bprocname\b" > /dev/null
    if [ $? -eq 0 ]; then
        echo "running"
    else
        echo "not running"
    fi
    

    更新3

    从更新后的问题中,我看到您正在从init脚本运行它。pgrep与脚本本身匹配总是有危险的。尝试:

    pgrep Processname | grep -q -v $$
    if [ $? -eq 0 ]; then
        echo "running"
    else
        echo "not running"
    fi
    

    从pgrep匹配项中排除脚本的PID。

    更新4

    (最后更新?手指交叉)

    如果init脚本是通过“service”命令运行的,那么我们也需要过滤掉父PID。怎么样:

    pgrep Processname | grep -v $$ | grep -q -v $PPID
    if [ $? -eq 0 ]; then
        echo "running"
    else
        echo "not running"
    fi
    
        2
  •  2
  •   Stephen Darlington    15 年前

    可能是因为 grep "processName" 发现自己。昨天我发现了这个同样的问题,除了 xarg 将结果发送给 kill

    作为另一种选择,您可以尝试 pgrep 命令而不是字符串 ps 和各种 grep S:

    sd@camel:~$ pgrep bash
    415
    3477
    sd@camel:~$ echo $?
    0
    sd@camel:~$ pgrep arf
    sd@camel:~$ echo $?
    1
    
        3
  •  1
  •   Rob Wells    15 年前

    G'Day.

    作为旁白,而不是

    ps ax | grep -v grep | grep "processName"
    

    试着去做

    ps ax | grep "[p]rocessName"
    

    ps正在列出grep函数,因为它在进程列表中看到字符串“grep processname”,而grep正在为字符串“processname”传递该字符串。

    对“[p]p rocessname”的grepping将只匹配“p rocessname”,而不匹配字符串“grep[p]p rocessname”。

        4
  •  -1
  •   ennuikiller    15 年前

    你没有做测试。在测试条件周围放置括号,如下所示:

    如果[测试条件]