if语句始终求值为TRUE

时间:2009-11-11 14:00:48

标签: linux bash unix process

无论我的进程是启动还是停止,是否有任何理由为什么此脚本始终返回“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 个答案:

答案 0 :(得分:16)

请改为尝试:

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”是否找到了它正在寻找的东西。

<强>更新

如果您的流程名称非常短(例如“杯子”),您可能会得到误报,因为它可能与其他流程相匹配(比如“cupsd”)。你可以通过让grep匹配整个单词来克服这一点 - 添加“-w”标志。

并不是说这种技术并不完美。您最终可能会在用户名/日期字段中匹配条目。如果发生这种情况,请查看“man ps”并在执行grep之前更有选择性地打印出来的内容。或者,使用awk预过滤输出以仅提取显示进程/ cmd名称的列。 E.g:

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

(最后更新?手指交叉)

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

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

答案 1 :(得分:2)

可能因为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

答案 2 :(得分:1)

天儿真好,

顺便说一句,而不是

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

尝试

ps ax | grep "[p]rocessName"

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

“[p] rocessName”的Grepping将仅匹配“processName”,但不匹配字符串“grep [p] rocessName”。

答案 3 :(得分:-1)

你不做测试。将括号放在测试条件周围,如下所示:

如果[测试您的测试]