用Bash方式检查进程是否已在后台运行(并跳过基于此的重新执行)?


11

如果该进程尚未运行(在后台),我是否可以使bash命令行仅运行某个命令?

如果命令已在运行,该如何检查*?

(因此,我可以&&在它们之间添加下一个命令,以便仅在第一个为true时才执行下一个命令)。

*:测试,确定,发现,找出


3
ps -ef | grep -v grep | grep "process_name" || run_command_here
拉胡尔·帕蒂尔

1
您可以使用@RahulPatil pgrep "process_name"代替ps | grep | grep
匆匆忙忙

嗯,我忘记了..:D
Rahul Patil

1
您为什么不使用“锁定”文件,而当您第二次启动时,它只会在锁定文件消失时启动。
BitsOfNix 2013年

如果一个流程来检查最好的方法:stackoverflow.com/questions/3043978/...
特雷弗·博伊德·史密斯

Answers:



3

我不时使用这种技术:

$ pgrep <process name> || <process name>

在此之前,以前pgrep是这样进行的:

$ ps -eaf | grep -q <[p]rocess name> || <process name>

用位[p]使它grep不会被结果发现。

$ ps -eaf | grep -q [s]leep || sleep 10

2

这可能很棘手,因为您可以具有独立存在的同一流程的单独实例。例如,服务器侦听不同的端口,或者以不同的用户身份运行的服务。为了区分这些实例,您需要为其分配一个唯一的标签。标签通常是一个文件,但它可以是抽象名称空间中的本地套接字,TCP端口等-任何唯一的标识符都可以。当标签是文件时,它可以是包含进程ID(pidfile)的常规文件,也可以是文件正在侦听的命名管道或套接字等。理想情况下,标签是允许客户端连接的通信端点。那个过程。

这些不同种类的标签中的每种标签都会以不同的方式检查您要查找的实例是否已启动并正在运行。例如,对于本地文件套接字,请尝试连接到该套接字,如果在该套接字上没有侦听任何进程,则启动该进程。如果标记是pidfile,请检查是否存在具有该进程ID的进程,但是请注意该进程是易碎的,因为如果该进程已死亡,则可能有不相关的进程重用了其ID。请注意,如果两个客户端尝试在短时间内完成该过程,则他们可能都发现该过程不存在,并且都试图启动该过程。适当地保护自己免受这种种族状况的影响可能会很棘手。

当所有实例都由同一主管进程启动时,管理这些实例会更容易,并且该主管进程会检测实例何时死亡并做出相应反应。许多服务监视程序都可以做到这一点。

如果程序没有在已知的通信终结点上响应,并且没有由主管程序进行管理,则穷人的标记是一个pidfile:包含进程ID的文件。开始该过程时,请将pid写入具有预定名称的文件。当您需要该进程存在时,请阅读pidfile并查看是否存在具有该pid的进程。当您终止进程时,请清除pidfile。无监督的pidfile的最明显的问题是,如果进程死亡,则其pid可能会被一些不相关的进程重用。您至少应检查进程名称或进程可执行文件,以确保您在与正确的进程通信。许多unix变体都有pgrep命令:pgrep SOMENAME 列出名称中包含SOMENAME作为子字符串的进程,以及用于限制特定用户,要求完全匹配,更改使用“进程名称”的几种可能概念中的哪一个的附加选项,等等。


1

您可以使用这种方法:

if [[ -z $(ps -C appname -opid=) ]]; then
    appname && secondapp
fi

1

其他选项:

  • pgrep -xq processname
    • 仅匹配GNU / Linux中的前15个字符
    • 不包括OS X上的祖先
  • ps -eo comm= | sed 's|.*/||' | grep -xq processname
    • 仅匹配GNU / Linux中的前15个字符
    • sed 's|.*/||' 删除OS X上的目录名部分

在GNU / Linux中,ps -o comm将命令名截断为15个字符,pgrep并且ps -C仅与前15个字符匹配。

ps -C (匹配命令名称)在OS X上不受支持。

在OS X中,ps -o comm打印命令的绝对路径,ps -co comm仅打印命令名称。在GNU中,ps -o comm仅打印命令名称,并且-c具有不同的含义。

OS X的pgrep不包含祖先进程(如bash,Terminal或Launchd)-a。GNU的pgrep默认包含它们,并且不支持-a

grep -x并且pgrep -x不表示-F,因此-Fx在进程名称可以包含正则表达式字符时使用。


-C在我的cygwin中也不可用:)
n611x007 2013年

1

抱歉,所有这些解决方案均不支持contab,因为同一命令行在“ ps”结果中将出现两次。

所以这是我的:

## Test pour voir si le même script tourne déjà
## Un fichier .pid est utilisé pour stocké le numéro de process
## Si le pid est en train de tourner alors on sort.
lock_file=$0".pid"
[ -r $lock_file ] && read pid <$lock_file
if [ "$pid" -gt 1 ] && [ `ps --no-headers -p "$pid" | wc -l` -gt 0 ] ; then
    echo "WARNING : le process $pid tourne deja : $0"
    ps -edf | grep `basename $0` | grep -v grep
    echo "WARNING : Arrêt de cette instance ($$)."
    exit 7
fi
echo $$ >$lock_file

你对不起什么 什么是contab?您的意思是在cron工作中检查吗?
Anthon 2015年

0

与重击

#!/usr/bin/env bash

[[ $# -eq 0 ]] && { echo -e "Usage:\t\t $0 <Process_name>  <Command here>"; exit 1;  }

ifnotrun(){
        local p=$1
        if ! ps -C "$1" -opid=
        then
                cmd=($@)
                echo ${cmd[@]:1}
        else
                echo "Process \"$p\" Already Running.."
                exit 1
        fi

}

ifnotrun $*

注意:- echo如果输出看起来确定,则删除。


0

我将解释在beckgreoud中运行命令的情况。“ $!” 保存最后一个后台进程的PID。因此,您可以按照上面的答案使用它在过程表中找到它:

sleep 4 &
ps -ef | grep -w  $!  ...

内置命令“ jobs”-试试这个:

sleep 4&
J=`jobs`
while [ "$J" ]; do
        sleep 1
        jobs # This line flush the jobs' bufer.
        J=`jobs`
done

关于“ &&”选项

代替&&使用命令wait。在以下示例中,myproc2将在myproc1完成之前不运行:

myproc1 &
wait
myproc2

0

获取您的过程状态:

ps -lp $(pgrep <YOUR_PROCESS_NAME>) | tail -1 | awk '{print $11}'

参考:

D    uninterruptible sleep (usually IO)
R    running or runnable (on run queue)
S    interruptible sleep (waiting for an event to complete)
T    stopped, either by a job control signal or because it is being traced
W    paging (not valid since the 2.6.xx kernel)
X    dead (should never be seen)
Z    defunct ("zombie") process, terminated but not reaped by its parent

例如,我已使用它在tmux会话中有条件地播放或暂停我的sox过程:

/usr/local/bin/tmux if-shell -t sox "[ $(ps -lp $(pgrep sox) | tail -1 | awk '{print $11}') == 'T' ]" \
  'send -t sox "fg" Enter' \
  'send -t sox C-z'

-1

您可以在脚本中使用它:

if [ `ps -ef | grep "script.sh" | grep -v grep | wc -l` -gt 1 ] ; then
echo "RUNNING...."
else
echo "NOT RUNNING..."
fi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.