我使用此命令来获取以特定名称(在循环中)运行的任何进程的计数,然后进一步确定计数,但有时它会为所有进程提供错误的答案,有时会为同一循环中的少数进程提供错误的答案。在某些服务器上根本不会有任何问题。当我手动检查相同内容时,结果发现是错误的
check_process() {
process_count=$(ps -eaf | grep -v grep | grep "$1" | wc -l)
if [ "${process_count}" -eq 1 ]; then
PROCESS_EXISTS=0
echo $1 " is running"
else
PROCESS_EXISTS=1
echo $1 " is not running"
fi
}
我还想提一下,它曾经工作得很好,近两年了,直到最近 2-3 个月才开始出现问题。
答案1
ps -f
给出如下输出:
chazelas 11042 10528 1 08:49 ? 00:00:03 /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -prefsLen 7847 -prefMapSize 699608 -parentBuildID 20200720193547 -appdir /usr/lib/firefox/browser 10528 true tab
grep "$1"
在许多帐户上,返回给定进程名称的行是错误的:
$1
如果以 开头,则会失败-
。你需要grep -e "$1"
或grep -- "$1"
.在将任意数据传递给命令时,您确实应该养成使用选项结束定界符的习惯。grep
采用正则表达式模式进行匹配(即re
ingrep
)。例如,因此grep a.py
会匹配。aspy
您可以使用grep -F
来搜索子字符串。ps -f
不报告过程名字但过程论点(包括argv[0]
按照惯例通常是命令的路径)。- 您正在查找正则表达式/子字符串,而不限制它匹配的行内的位置。例如,上面的
$1
==as
会匹配as
in 。或者它可以匹配除 之外的其他参数。chazelas
argv[0]
grep | wc -l
是grep -c
。
这里,有一个(非标准但非常常见)命令来按名称(或其他重要标准)匹配进程:pgrep
pgrep -xc -- "$1"
会c
计算哪些进程姓名ps
(就像without报告的那样-f
)ex
正好匹配 中的正则表达式$1
。使用-f
,pgrep
匹配完整的参数列表(由 报告ps -f
)而不是进程名称。
这就留下了进程名称包含正则表达式运算符的问题(如上所述.
)。不幸的是,pgrep
没有-F
选项可以进行字符串比较而不是正则表达式匹配,因此您需要转义其中的正则表达式运算符。
另一种选择是告诉ps
仅报告进程名称,然后用于grep -xF
执行x
固定F
字符串比较:
ps -Ao comm= | grep -Fxce "$1"
替换comm
为args
打印参数列表(尽管可能被截断,某些ps
实现允许一个或多个参数-w
提高行长度限制)而不是进程名称。
在任何情况下,任何用户都可以使用任何名称和任何参数列表创建任何进程,因此按名称查找进程非常脆弱。任何人都可以通过启动具有相同名称和相同参数列表的进程来运行完全不同的命令,从而欺骗您认为您的进程就在那里。
通常最好检查您的流程提供的服务的可用性或保留其当前正在使用的某些资源。
在某些情况下,您可以在搜索中添加其他条件,例如有效 uid ( -u
in pgrep
) 或当前正在运行的可执行文件的路径。
在 Linux 上并使用zsh
:
pids=(/proc/<->(Nnu[chazelas]e['[[ $REPLY/exe -ef /usr/bin/sleep ]]']:t]))
例如,将以用户身份存储在文件$pids
中运行代码的进程的 ID中,您可以使用它来检查该列表是否不为空。 (用或替换以搜索中的命令)。/usr/bin/sleep
chazelas
if (($#pids > 0)); then...
/usr/bin/sleep
=sleep
$commands[sleep]
sleep
$PATH
更一般地说,最好依靠服务经理来管理服务和流程。现代的诸如此类systemd
将提供可靠地做到这一点的设施。
答案2
- 在某些情况下可能会出现一些奇怪的时间效应。
- 根据您要查找的内容,可能还有其他匹配项。如果没有
wc
.由于您检查的方式,如果有两个匹配项,您会报告它没有运行。 (即考虑使用-ge
而不是-eq
。) - 更有效的测试可以是使用
killall -0 commandname
.使用信号 0 进行终止不会发送实际信号,但仍会进行所有错误检查,包括如果未发现任何内容则显示错误。 (一个缺点:终止不属于您自己的进程也是一个错误,除非您是 root。该--user
选项可以帮助解决此问题。)