问题描述
我如何确定一个进程是否正在运行,然后让一个bash脚本根据这个条件执行一些东西?
例如:
-
如果进程
abc
正在运行,请执行此操作 -
如果它没有运行,那就这样做。
最佳解决方案
一个bash脚本来做这样的事情看起来像这样:
#!/bin/bash
# Check if gedit is running
# -x flag only match processes whose name (or command line if -f is
# specified) exactly match the pattern.
if pgrep -x "gedit" > /dev/null
then
echo "Running"
else
echo "Stopped"
fi
该脚本只是检查程序”gedit”是否正在运行。
或者你只能检查程序是否不像这样运行:
if ! pgrep -x "gedit" > /dev/null
then
echo "Stopped"
fi
次佳解决方案
任何使用类似ps aux | grep abc
或pgrep abc
的解决方案都存在缺陷。
为什么?
由于您没有检查特定进程是否正在运行,因此您正在检查是否有任何正在运行的进程与abc
匹配。任何用户都可以轻松创建并运行名为abc
的可执行文件(或其名称或参数中包含abc
的可执行文件),从而导致您的测试出现误报。您可以向ps
,grep
和pgrep
应用各种选项来缩小搜索范围,但仍然无法获得可靠的测试。
那么如何可靠地测试某个运行过程呢?
这取决于你需要什么测试。
我想确保服务abc正在运行,如果没有,请启动它
这是init和upstart的用武之地。他们将启动服务并确保其pid存储在pidfile中。尝试再次启动服务(通过init或upstart),它将检查pidfile,并且如果它不存在则启动它,或者如果它已经在运行,则启动它。这仍然不是100%可靠的,但它和你一样接近。
其他解决方案请参见How can I check to see if my game server is still running…。
abc是我的脚本。我需要确保只有一个脚本实例正在运行。
在这种情况下,使用lockfile或lockdir。例如。
#!/usr/bin/env bash
if ! mkdir /tmp/abc.lock; then
printf "Failed to acquire lock.\n" >&2
exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT # remove the lockdir on exit
# rest of script ...
有关其他锁定方式,请参阅Bash FAQ 45。
第三种解决方案
这是我使用的:
#!/bin/bash
#check if abc is running
if pgrep abc >/dev/null 2>&1
then
# abc is running
else
# abc is not running
fi
用简单的英文表示:如果’pgrep’返回0,则进程正在运行,否则不是。
相关阅读:
Bash脚本:: String Comparisons
Ubuntu手册pgrep
第四种方案
我通常在我的脚本上有一个pidof -x $(basename $0)
来检查它是否已经在运行。