如果想检查一个进程是否正在运行,如果不是,则启动它。 我的脚本下面是越野车,总是说一个进程正在运行。 哪里不对?
$ ./check_n_run thisisnotrunning ./check_n_run: thisisnotrunning is already running
这是脚本:
$ cat check_n_run #!/bin/sh USAGE="usage: $0 processname" if [ $# -ne 1 ] ; then echo "$USAGE" >&2 exit 1 fi ps ax | grep -v grep | grep $1> /dev/null if [ $? -eq 1 ] then echo "$1 not running" # start here else echo "$0: $1 is already running" >&2 fi exit 0
你的脚本中的问题是(使用你正在使用的shell)在一个pipe道中,每个命令运行在一个单独的子shell中,它们的状态都不会传播到父进程。 所以在command1 | command2之后 command1 | command2 , $? 总是0。
即使你修正了它,你的脚本也是非常不可靠的:它将把包含你的过程的名字作为子串匹配进程。 Linux提供的pidof命令完全符合你所要做的。
然而,这仍然不是理想的,因为可能有另一个同名的进程。 最好是使用适当的服务pipe理器,比如Debian / Ubuntu的start-stop-daemon ,或者一个暴发户服务。 Wrikken提到的lockfile(来自procmail)也是一种可能性。
只要ps / grep不会出错,$? 应该是0。
编辑:根据吉尔斯(我没有壳可用atm):
在ksh / zsh中,$? 如果grep既不能find匹配也不会出错
我通常倾向于在启动这些进程时使用lockfile …
lockfile /path/to/lockfile && (do_something; rm -f /path/to/lockfile)
虽然您的脚本可以被修改为:
procs=`ps ax | grep -v grep | grep -c $1` if [ $procs -lt 1 ] then ....
问题:如果你的系统和我的系统是类似的,那么ps ax的输出不仅包括进程名称,还包括用于运行它的整个命令行。 所以当你跑步
./check_n_run thisisnotrunning
ps ax的输出将会包含该行,所以grep总是会find一个不能运行的结果。 这就解释了为什么你的脚本总是报告程序正在运行。
为了解决这个问题,有几个select。 正如Gilles所说,最好的方法是使用start-stop-daemon来启动和停止脚本。 如果这不可能,可以使用pidof来检测给定的可执行文件是否正在运行。 如果由于某些原因无法使用,您可以使用
ps -C thisisnotrunning
它只打印给定命令名称的进程。
我认为你尝试了艰辛的方式。 我不知道你使用了什么发行版,但是尝试看到path/var/run 。 这是一个包含每个进程的PID的目录。
试试ls *something* 。 如果有东西是回报,那么你的过程正在运行。 否则它不是。