gpt4 book ai didi

linux - Bash:if语句总是成功

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:44:57 25 4
gpt4 key购买 nike

我有以下 if 语句来检查服务(在本例中为 newrelic-daemon)是否正在运行...

if [ $(ps -ef | grep -v grep | grep newrelic-daemon | wc -l) > 0 ]; then
echo "New Relic is already running."

问题是它总是返回 true,即“New Relic 已经在运行”。即使当我单独运行 if 条件时......

ps -ef | grep -v grep | grep newrelic-daemon | wc -l

...它返回 0。我希望它在这里什么都不做,因为返回的值是 =0,但我的 IF 条件显示 >0。

我是不是忽略了什么?

最佳答案

您正在尝试在 [...]> 中进行数值比较。那行不通;要将值作为数字进行比较,请改用 -gt:

if [ "$(ps -ef | grep -v grep | grep -c newrelic-daemon)" -gt 0 ]; then

如果出现严重错误(例如 $PATH 设置错误并且 shell 找不到 grep),命令扩展周围的引号可以防止出现语法错误。由于您专门标记了此 bash,因此您也可以只使用 [[...]] 而不是 [ ...] 并且不带引号。

作为另一个特定于 Bash 的选项,您可以使用 ((...)) 而不是任何一种形式的方括号。如果出现任何问题,此版本更有可能生成语法错误(因为算术表达式语法确实希望所有参数都是数字),但它允许您使用更自然的比较运算符:

if (( "$(ps -ef | grep -v grep | grep -c newrelic-daemon)" > 0 )); then

在这两种情况下,我都使用了 grep -c 而不是 grep | wc -l;这样我就避免了一个额外的进程和一堆进程间 I/O,这样 wc 就可以计算 grep 已经枚举的行。

但是由于您只是检查是否存在任何匹配项,因此您不需要执行任何一项操作;如果最后一个 grep 找到任何东西,它将以 true 状态退出,如果没有找到,则返回 false,所以你可以这样做:

if ps -ef | grep -v grep | grep -q newrelic-daemon; then

(-q 阻止 grep 实际打印出匹配的行。)

此外,如果您要查找的进程名称是文字字符串而不是变量,我最喜欢的此任务技巧是像这样修改该字符串,而不是通过额外的 grep -v grep :

if ps -ef | grep -q 'newrelic[-]daemon'; then

您可以选择任何字符放在方括号中;重点是创建一个匹配目标进程名称但匹配模式本身的正则表达式模式,因此 grep 进程找不到它自己的 ps 行。

最后,由于您标记了此 linux,请注意大多数 Linux 发行版都附带了 ps + grep 命令组合,称为 pgrep ,无需构建管道即可为您完成此操作:

if pgrep newrelic-daemon >/dev/null; then 

(pgrep 的 MacOS/BSD 版本接受 -q 选项,如 grep,这样您就可以不用 >/dev/null 重定向,但我在 Linux 系统上找到的版本似乎没有该选项。)

还有pidof;我还没有遇到过有 pidof 而没有 pgrep 的系统,但是如果你遇到了一个,你可以用同样的方式使用它:

if pidof newrelic-daemon >/dev/null; then 

关于linux - Bash:if语句总是成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42558382/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com