if语句始终求值为TRUE

Mik*_*ike 7 unix linux bash process

无论我的进程是启动还是停止,是否有任何理由为什么此脚本始终返回"正在运行"?

if ps ax | grep -v grep | grep "processName" > /dev/null
then
   echo $"running"
else
   echo $"not running"
fi
Run Code Online (Sandbox Code Playgroud)

非常感谢你

更新: 我添加了我的脚本的完整示例,也许其他地方有问题.

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
Run Code Online (Sandbox Code Playgroud)

更新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
Run Code Online (Sandbox Code Playgroud)

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

Sha*_*hin 16

试试这个:

ps aux | grep -q "[p]rocessName"
if [ $? -eq 0 ]; then
    echo "running"
else
    echo "not running"
fi
Run Code Online (Sandbox Code Playgroud)

processName的第一个字母周围的括号表示不需要"grep -v grep",而-q表示我们不需要管道到/ dev/null

$?为您提供上一个执行命令的返回码.因此,测试它是否为0将表明"grep"是否找到了它正在寻找的东西.

更新

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

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

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

更新2

你也可以按照下面的答案建议使用pgrep.

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

pgrep "\bprocname\b" > /dev/null
if [ $? -eq 0 ]; then
    echo "running"
else
    echo "not running"
fi
Run Code Online (Sandbox Code Playgroud)

更新3

从更新的问题,我看到你是从init脚本运行它.pgrep总是存在匹配脚本本身的危险.尝试:

pgrep Processname | grep -q -v $$
if [ $? -eq 0 ]; then
    echo "running"
else
    echo "not running"
fi
Run Code Online (Sandbox Code Playgroud)

这从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
Run Code Online (Sandbox Code Playgroud)

  • 嘿,这实际上是一个漂亮的技巧与[p] rocessname - +1证明老狗可以学习新的技巧. (4认同)