问题描述
我想检查特定的进程是否已经在运行。
我参考了this Q&A。
但是我没有任何具体的解决方案。以下是我尝试的示例:我创建了abc.sh
文件并在后台运行此脚本,例如sh abc.sh &
。
现在,此文件在后台运行,我启动了ps aux | grep "abc"
命令。
以下是此命令的输出:
prakash 3594 0.0 0.0 4388 820 pts/0 S+ 16:44 0:00 grep --color=auto abc
之后,我停止abc.sh
运行脚本并触发相同的命令ps aux | grep "abc"
命令。
但我得到相同的输出,如:
prakash 3594 0.0 0.0 4388 820 pts/0 S+ 16:44 0:00 grep --color=auto abc
还有其他方法可以找到该进程正在运行吗?
最佳答案
每个进程都将在ps aux
的输出中列出;无论是跑步,睡觉,僵尸还是停止。
但是,根据您的情况,由于您使用sh abc.sh
运行了该进程,因此sh
是正在运行的应用程序( shell 程序),而不是abc.sh
。因此,ps aux
将不包含进程abc.sh
,因为grep
无法产生任何结果。
因此,正确的使用方法是:
ps aux | grep sh
这也可能会返回其他正在运行的进程,该进程的输出ps aux
中的任何位置都有字符串sh
。
您应该注意,当ps aux
的输出的STAT
为R
时,该过程将为”running”。如果不是,则它在您触发命令检查正在运行的进程的实例上未运行。可以在ps的手册页中找到不同的过程状态:
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
您也可以运行top
命令来检查该进程是正在运行还是正在休眠,以及正在消耗的CPU和RAM数量。 (这将再次将您的进程列为sh
)。
但是,如果您确实希望将进程列为abc.sh
,那么您应该将脚本的第一行作为运行:
#!/bin/sh
这样 shell 程序将知道要使用哪个应用程序来运行脚本(在本例中为sh,将其更改为bash的#!/bin/bash
),然后使用以下命令为该进程提供可执行权限:
chmod +x /path/to/abc.sh
将/path/to/
替换为abc.sh
文件的位置,然后使用以下命令运行abc.sh
/path/to/abc.sh
再次用abc.sh
文件的位置替换/path/to/
。
次佳答案
我的grep
问题是它是whole-line解析器。在您的示例中,您正在搜索”abc”,但它正在回退grep
的实例(正在寻找”abc”)。有点循环。您可以将其过滤掉,但我发现所有这些都有些反常。
我会向awk
求助。
ps aux | awk '$12=="abc.sh"'
awk
根据空白将行划分为字段(默认情况下)。字段$ 11 +是命令列,因此,如果命令为“ sh abc.sh …”,则$11
将为sh
而$12
将为abc.sh
。
如果要使用Bash的&&
和||
运算符控制输出或链接,可以,但是需要更加聪明。如果未找到任何内容,grep
将以状态代码1退出(技术故障,触发||
),但awk
将始终退出代码0。我们可以通过告诉它找到内容退出并返回1(如果未找到)来更改此代码:
ps aux | awk '$12=="abc.sh" {exit 0} END{exit 1}' && echo running || echo not running
当然,如果您只关心将输出写入屏幕,则可以在awk
中完成所有操作:
ps aux | awk '$12=="abc.sh" {print "running"; exit} END{print "not running"}'
第三种答案
检查当前bash会话中在后台启动的进程(例如sh abc.sh &
)是否已经运行的正确方法是使用jobs
内置命令。
例:
$ sh abc.sh &
[1] 6917
$ jobs
[1]+ Running sh abc.sh &
这意味着在后台启动的sh abc.sh
进程正在运行。如果该过程完成,您将看到以下内容:
[1]+ Done sh abc.sh
如果您有更多在后台运行的进程,则可以使用以下命令将输出限制为sh abc.sh
进程:
jobs sh
有关更多信息,请参见help jobs
。
以上方法仅在当前bash会话中有效。但是,如果您在另一个bash会话中(例如,在另一个终端窗口或选项卡中或在脚本中),除了:
ps aux | grep "[s]h bin/test.sh"
您还可以使用:
pgrep -a sh
对我来说,这似乎更简单。如果在输出中看到键入的命令(在本例中为sh abc.sh
),则表明该进程仍在运行。如果不是,则该过程已完成。
第四种答案
如果您的脚本当前正在运行,则必须由ps aux
命令显示。如果ps
未显示该脚本,则可能是您的脚本执行当前已终止。
像这样的ps
输出表明您的脚本当前未运行,
$ ps aux | grep hm.sh
avinash 6386 0.0 0.0 15940 932 pts/16 S+ 17:34 0:00 grep --color=auto hm.sh
如果显示如下,则表明您的脚本当前正在运行。
$ ps aux | grep hm.sh
avinash 6454 0.0 0.0 16616 1384 pts/16 S+ 17:35 0:00 /bin/bash ./hm.sh
avinash 6535 0.0 0.0 15940 932 pts/27 R+ 17:35 0:00 grep --color=auto hm.sh
这完全基于脚本的内容。
例如,如果您创建这样的脚本。执行时显示消息HI。显示输出需要花费几秒钟,并在产生最终结果后被终止。
#!/bin/bash
echo "HI"
但是如果您的脚本是这样的,
#!/bin/bash
sudo apt-get update
需要几分钟时间才能终止该过程。同时,如果您运行ps aux | grep filename
命令,它将显示在输出中。因为脚本当前正在运行。