如何确定进程是否正在运行并使用它来创建条件shell脚本?

如何确定某个进程是否正在运行,然后让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等解决方案的解决方案 ps aux | grep abcpgrep abc有缺陷。

为什么?

因为您没有检查特定进程是否正在运行,所以您正在检查是否有任何正在运行的进程与abc匹配。 任何用户都可以轻松地创建和运行名为abc的可执行文件(或者在其名称或参数中包含abc的可执行文件),从而导致测试误报。 有许多选项可以应用于psgreppgrep来缩小搜索范围,但是你仍然无法获得可靠的测试。

那么如何可靠地测试某个运行过程呢?

这取决于你需要测试的内容。

我想确保服务abc正在运行,如果没有,请启动它

这就是init和upstart的用途。 他们将启动服务并确保其pid存储在pidfile中。 尝试再次启动服务(通过init或upstart),它将检查pid文件,如果不存在则启动它,或者如果它已经运行则中止。 这仍然不是100%可靠,但它就像你得到的那样接近。

请参阅如何查看我的游戏服务器是否仍在运行…以获取其他解决方案。

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 Scripting :: String Comparisons

Ubuntu手册pgrep

我的脚本通常有一个pidof -x $(basename $0)来检查它是否已经运行。

重复@ rommel-cid的想法,你可以使用pidof和|| (||)如果进程不存在则运行命令,如果进程存在则运行某些命令,从而创建快速if / then / else条件。 例如,这里有一个正在运行的进程(我的chrome浏览器,其进程名称为“chrome”)和一个不存在的进程测试。 我使用1> / dev / null来抑制标准输出,因此它不会打印:

 $ (pidof chrome 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run instea\ d" its running? ok, so am i then $ (pidof nosuchprocess 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run\ instead" it's not running? ok i'll run instead $ 

我想到的第一件事就是你的问题:
ps aux | grep -i abc 如果进程正在运行, ps aux | grep -i abc将显示进程的详细信息。 您可以匹配其运行的行数或时间,并与零或任何其他操作进行比较。 当您运行上面的命令时,它将显示至少一行输出,即有关由thi grep命令创建的进程的详细信息。所以请注意这一点。
这应该是一个简单的黑客。 把它放在bash脚本中,看看它是否有用。

使用start-stop-daemon

 /sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2 

它像普通用户一样工作。

我发现@John Vrbanac发布的接受的答案对我不起作用,@ geirha发布的答案没有回答原来的问题。

John Vrbanac的解决方案无法检查PHP进程是否正在运行,我正在运行CentOS 7。

@ geirha的答案只能确保实例在启动另一个实例之前尚未运行。 这不是原始问题,最初的问题是检查进程是否正在运行。

这对我有用:

假设我的进程在其进程名称中包含字符串“Jane”。 这将发现它是否正在运行。 这适用于BASH和PHP脚本。

 ps -aux | grep "[J]ane" > /dev/null 2>&1 if [[ "$?" == "0" ]]; then echo "It's running" else echo "It's not running" fi 
 ## 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 &) 

注意pgrep -x lxpanelpidof lxpanel仍然报告lxpanel即使在它失效时lxpanel运行(僵尸); 因此,为了获得活跃且正在运行的过程,我们需要使用psgrep

截至2016年9月23日,pgrep似乎需要一个选项“-x”才能使muru的脚本正常工作。

 #!/bin/bash if pgrep -x "conky" > /dev/null 2>&1 then echo "conky running already" else echo "now starting conky" conky fi exit 0 

我在Ubuntu 16.04.1机器上试过并测试了上面的脚本。 请享用!

 #!/bin/bash while [ true ]; do # Endless loop. pid=`pgrep -x ${1}` # Get a pid. if [ -z $pid ]; then # If there is none, ${1} & # Start Param to background. else sleep 60 # Else wait. fi done 

isProcessRunning(){if [$(pidof $ 1)> / dev / null]; 那么retval =’true’; else retval =’false’; 网络连接; echo $ retval; }

isProcessRunning geany

真正