我正在尝试使用以下代码检查进程是否正在运行:
SERVICE="./yowsup/yowsup-cli"
RESULT=`ps aux | grep $SERVICE`
if [ "${RESULT:-null}" = null ]; then
echo "not running"
else
echo "running"
fi
但它一直在回显正在运行,尽管实际上并没有在运行。我意识到grep本身就作为一个结果出现了,这就是问题所在。
如何跳过grep,仅检查进程?
我正在尝试使用以下代码检查进程是否正在运行:
SERVICE="./yowsup/yowsup-cli"
RESULT=`ps aux | grep $SERVICE`
if [ "${RESULT:-null}" = null ]; then
echo "not running"
else
echo "running"
fi
使用pgrep
命令:
if pgrep "$SERVICE" >/dev/null 2>&1 ; then
echo "$SERVICE is running"
fi
或者:if pgrep -f "/path/to/$SERVICE" >/dev/null 2>&1 ; then
echo "$SERVICE is running"
fi
注意:
pgrep
将其参数解释为一个 正则表达式,因此包含正则表达式字符的路径可能无法匹配或产生误报 (例如,pgrep -f /home/user/projects/c++/application/executable
由于+
, 无法按预期工作)。可以通过转义相关字符来解决此问题 (例如,pgrep -f /home/user/projects/c\+\+/application/executable
)。
pgrep -f <pattern>
对正在运行的进程的整个命令行匹配指定的模式。因此,它将匹配出现为其他进程参数的路径 (例如,在一个终端中运行 nano /usr/bin/sleep
并在另一个终端中运行 pgrep -f /usr/bin/sleep
-> pgrep
报告 nano
的 pid,因为它的命令行中包含/usr/bin/sleep
作为参数)。为防止这些误报,请在模式前加上脱字符 (^
),以强制 pgrep
只匹配命令行的开头 (例如,pgrep -f ^/usr/bin/sleep
)。
pgrep
解释指定的参数作为“模式”,因此它并不是那么可靠。结果,包含正则表达式字符的路径将无法匹配或产生误报,例如,pgrep -f "/home/user/projects/c++/application/executable"
的效果与预期不符。 - Fonicgrep
有 -F
选项用于固定字符串搜索(无模式),但是 pgrep 显然没有这个选项。 - hek2mglps ax -o pid,cmd | awk -v search='search_string' '{pid=$1;$1=""} index($0, search){print pid}'
... 在此示例中,search_string
可包含任何类型的特殊字符。 - hek2mglpgrep -f
实际上并不可靠,最好完全避免使用。请尝试以下操作:在一个终端中运行 nano /usr/bin/sleep
,在另一个终端中运行 pgrep -f /usr/bin/sleep
-> pgrep
将报告 nano
的 pid,因为它的命令行中包含 /usr/bin/sleep
。看起来 pgrep -f
盲目地匹配整个命令行,包括参数。我认为这使得 pgrep -f
完全不适用于此用例。 - Fonic-f
。如果你想要的话,我会把这个留给你?与此同时,你的注释与答案保持同步。再次感谢,非常感谢! - hek2mgl对于没有pgrep
命令的系统,您可以使用:
service="[.]/yowsup/yowsup-cli"
if ps aux | grep -q "$service"; then
echo "not running"
else
echo "running"
fi
[.]
会强制grep
不将自己列出,因为它不符合[.]
的正则表达式。grep -q
来避免命令替换步骤。grep
命令会出现在ps
列表中,因此只有在交互式检查时才能正常工作。$ ps -ef | grep bash
...
myaut 19193 2332 0 17:28 pts/11 00:00:00 /bin/bash
myaut 19853 15963 0 19:10 pts/6 00:00:00 grep --color=auto bash
最简单的方法是使用pidof
。它接受完整路径和可执行文件名:
service="./yowsup/yowsup-cli" # or service="yowsup-cli"
if pidof "$service" >/dev/null; then
echo "not running"
else
echo "running"
fi
有一种更强大的pidof
版本-- pgrep
。
然而,如果您从一个脚本启动程序,则可以将其PID保存到文件中:
service="./yowsup/yowsup-cli"
pidfile="./yowsup/yowsup-cli.pid"
service &
pid=$!
echo $pid > $pidfile
然后使用pgrep
命令检查它:
if pgrep -F "$pidfile" >/dev/null; then
echo "not running"
else
echo "running"
fi
ps
+ grep
,pgrep
和 pidof
出现的问题(见下文的 优点):
# Check if process is running [$1: path to executable]
function is_process_running() {
local path="$1" line
while read -r line; do
[[ "${line}" == "${path}" || "${line}" == "${path} "* ]] && return 0
done < <(ps -e -o command=)
return 1
}
is_process_running "./yowsup/yowsup-cli" && echo "running" || echo "not running"
解释:
ps -e -o command=
列出所有进程,仅输出每个进程的命令行,省略标题行while read -r line; do ... done < <(ps ...)
逐行处理由ps
生成的输出[[ "${line}" == "${path}" || "${line}" == "${path} "* ]]
检查行是否完全匹配路径或路径+空格+参数优势:
-F
或pgrep
的情况下会使grep
报错,例如:/home/user/projects/c++/application/executable
(有关详细信息,请参见此答案中的注意事项)ps
+ grep
/ pgrep
时报告路径作为其他进程的某些参数而导致误报的问题(例如:nano /usr/bin/sleep
+pgrep -f /usr/bin/sleep
->错误地报告nano
进程的pid)pidof
对从PATH
运行的进程误报的问题(例如:sleep 60s &
+pidof /tmp/sleep
->错误地报告从/usr/bin/sleep
运行的sleep
进程的pid,而不管/tmp/sleep
是否实际存在)## bash
## function to check if a process is alive and running:
_isRunning() {
ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1
}
## example 1: checking if "gedit" is running
if _isRunning gedit; then
echo "gedit is running"
else
echo "gedit is not running"
fi
## example 2: start lxpanel if it is not there
if ! _isRunning lxpanel; then
lxpanel &
fi
## or
_isRunning lxpanel || (lxpanel &)
function isrunning()
{
pidof -s "$1" > /dev/null 2>&1
status=$?
if [[ "$status" -eq 0 ]]; then
echo 1
else
echo 0
fi
)
if [[ $(isrunning bash) -eq 1 ]]; then echo "bash is running"; fi
if [[ $(isrunning foo) -eq 1 ]]; then echo "foo is running"; fi
current_pid="$$" # get current pid
# Looking for current pid. Don't save lines either grep or current_pid
isRunning=$(ps -fea | grep -i $current_pid | grep -v -e grep -e $current_pid)
# Check if this script is running
if [[ -n "$isRunning" ]]; then
echo "This script is already running."
fi
SERVICE="./yowsup/yowsup-cli"
RESULT=`ps aux | grep $SERVICE|grep -v grep`
if [ "${RESULT:-null}" = null ]; then
echo "not running"
else
echo "running"
fi