通常,尝试使用简单方法ps
并grep
确定给定进程是否正在运行是个坏主意。
使用pgrep
此功能会更好:
if pgrep "varnish" >/dev/null; then
echo "Varnish in running"
else
echo "Varnish is not running"
fi
请参阅手册pgrep
。在某些系统上(可能不在Linux上),您将获得一个-q
标志,该标志对应于grep
无需重定向到的同一标志/dev/null
。还有一个-f
标志在完整的命令行上而不是仅在进程名称上执行匹配。也可以使用将该匹配限制为属于特定用户的进程-u
。
安装pgrep
还使您可以访问,pkill
从而可以根据进程的名称来发信号通知进程。
另外,如果这是一个服务守护进程,并且您的Unix系统可以查询它的信息(例如,它是否已启动并正在运行),那么这就是检查它的正确方法。
在Linux上,您具有systemctl
(systemctl is-active --quiet varnish
如果正在运行,则将返回0,否则将返回3),在OpenBSD上,您具有rcctl
,等等。
现在到您的脚本:
在脚本中,您将解析来自的输出ps ax
。此输出将包含脚本本身的名称,该名称check_varnish_pro.sh
显然包含字符串varnish
。这给您带来了误报。如果在测试时没有-q
标记的情况下运行它,则可能会发现它grep
。
#!/bin/bash
ps ax | grep '[v]arnish'
运行它:
$ ./check_varnish_pro.sh
31004 p1 SN+ 0:00.04 /bin/bash ./check_varnish_pro.sh
另一个问题是,尽管您尝试通过使用模式来“隐藏”该grep
过程以免被grep
自身检测到[v]
。如果您碰巧在其中有文件或目录的目录中运行脚本或命令行,则该方法将失败varnish
(在这种情况下,您将再次得到误报)。这是因为该模式未引用,并且外壳程序将使用它来执行文件名遍历。
看到:
bash-4.4$ set -x
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep '[v]arnish'
bash-4.4$ touch varnish
+ touch varnish
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep varnish
91829 p2 SN+p 0:00.02 grep varnish
文件的存在varnish
将导致外壳程序[v]arnish
用文件名替换,varnish
并且您会在进程表(grep
进程)中找到模式。