如果该进程尚未运行(在后台),我是否可以使bash命令行仅运行某个命令?
如果命令已在运行,该如何检查*?
(因此,我可以&&
在它们之间添加下一个命令,以便仅在第一个为true时才执行下一个命令)。
*:测试,确定,发现,找出
pgrep "process_name"
代替ps | grep | grep
如果该进程尚未运行(在后台),我是否可以使bash命令行仅运行某个命令?
如果命令已在运行,该如何检查*?
(因此,我可以&&
在它们之间添加下一个命令,以便仅在第一个为true时才执行下一个命令)。
*:测试,确定,发现,找出
pgrep "process_name"
代替ps | grep | grep
Answers:
使用daemontools。您可以svok
用来检查服务/守护程序/后台进程当前是否正在运行。
有关其他方法,请参见:
这可能很棘手,因为您可以具有独立存在的同一流程的单独实例。例如,服务器侦听不同的端口,或者以不同的用户身份运行的服务。为了区分这些实例,您需要为其分配一个唯一的标签。标签通常是一个文件,但它可以是抽象名称空间中的本地套接字,TCP端口等-任何唯一的标识符都可以。当标签是文件时,它可以是包含进程ID(pidfile)的常规文件,也可以是文件正在侦听的命名管道或套接字等。理想情况下,标签是允许客户端连接的通信端点。那个过程。
这些不同种类的标签中的每种标签都会以不同的方式检查您要查找的实例是否已启动并正在运行。例如,对于本地文件套接字,请尝试连接到该套接字,如果在该套接字上没有侦听任何进程,则启动该进程。如果标记是pidfile,请检查是否存在具有该进程ID的进程,但是请注意该进程是易碎的,因为如果该进程已死亡,则可能有不相关的进程重用了其ID。请注意,如果两个客户端尝试在短时间内完成该过程,则他们可能都发现该过程不存在,并且都试图启动该过程。适当地保护自己免受这种种族状况的影响可能会很棘手。
当所有实例都由同一主管进程启动时,管理这些实例会更容易,并且该主管进程会检测实例何时死亡并做出相应反应。许多服务监视程序都可以做到这一点。
如果程序没有在已知的通信终结点上响应,并且没有由主管程序进行管理,则穷人的标记是一个pidfile:包含进程ID的文件。开始该过程时,请将pid写入具有预定名称的文件。当您需要该进程存在时,请阅读pidfile并查看是否存在具有该pid的进程。当您终止进程时,请清除pidfile。无监督的pidfile的最明显的问题是,如果进程死亡,则其pid可能会被一些不相关的进程重用。您至少应检查进程名称或进程可执行文件,以确保您在与正确的进程通信。许多unix变体都有pgrep命令:pgrep SOMENAME
列出名称中包含SOMENAME作为子字符串的进程,以及用于限制特定用户,要求完全匹配,更改使用“进程名称”的几种可能概念中的哪一个的附加选项,等等。
其他选项:
pgrep -xq processname
ps -eo comm= | sed 's|.*/||' | grep -xq processname
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
在进程名称可以包含正则表达式字符时使用。
抱歉,所有这些解决方案均不支持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
cron
工作中检查吗?
与重击
#!/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
如果输出看起来确定,则删除。
我将解释在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
获取您的过程状态:
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'
ps -ef | grep -v grep | grep "process_name" || run_command_here