首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >“如果pgrep”不再起作用,如果我使用[[或]

“如果pgrep”不再起作用,如果我使用[[或]
EN

Unix & Linux用户
提问于 2021-10-18 13:48:42
回答 1查看 1.4K关注 0票数 0

我试图检测进程(goland.sh)是否正在运行。我用这个:

代码语言:javascript
运行
复制
#!/bin/bash

if pgrep "goland.sh" >/dev/null 2>&1 ; then
    echo "running"
    exit 1
fi

echo "not running"

这是可行的,但我不明白两件事:

  1. 为什么如果我使用if [[ pgrep "goland.sh" >/dev/null 2>&1 ]] ; then,它不工作(它总是打印‘运行’,即使进程没有运行)
  2. 为什么如果我使用if [ pgrep "goland.sh" >/dev/null 2>&1 ] ; then,它不工作(它总是打印‘运行’,即使进程没有运行)

我怀疑1与如何解析>有关,但我对2完全一无所知。

EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2021-10-18 14:32:29

在shell的测试如何构造[ ... ] (或Bash情况下的[[ ... ]] )的工作方式方面,似乎存在误解。

  • if语句检查它后面的命令是否返回0的退出状态,这意味着“没有错误”,并被解释为"true“。如果是这样,则执行切换到脚本的then分支(参见巴什手册 )。
  • 如果找到了与模式匹配的进程,pgrep命令将返回0 (即"true")。这就是为什么只有在running的一个实例是活动的情况下才会得到goland.sh
  • [是一个特殊的命令(通常是shell内置的命令),它允许对文件、字符串和数字执行测试,如果开头括号和结尾括号之间的条件为真,则返回" true“。但是,它的设计是根据特定的语法检查一个或多个操作数上的操作是否为真,例如,如果一个数字(操作数1)大于(运算符)另一个操作数(操作数2)。例如,假设shell变量n的值为5,则测试将返回true,并且当用作if语句的测试命令时,执行将切换到then分支。
  • 定义了几个测试结构,以便您可以检查字符串是否为空、文件是否存在和/或可执行等等。但是,无论如何,您必须理解[ ... ]之间代码的正确语法,以确保得到预期的结果。

现在,您已经在测试构造括号中包含了一个“原始”shell命令。那么会发生什么在一定程度上取决于情况,但在任何情况下它都会构成语法错误,因为在方括号之间没有一个有效的运算符,因此有几个(常量)字符串标记。

  • 当使用[[ ... ]]时,您将立即得到一个语法错误,因为它是一个Bash语法元素,并且Bash识别错误的语法。
  • 但是,如果是[ ... ],您的命令就会悄悄地失败,因为[实际上是一个命令(尽管通常是内置的),它只希望它的参数对预定义的操作符有意义,并且期望它的最后一个参数是关闭的] --但是既然您已经将它的错误输出重定向到/dev/null,错误消息就会丢失。
  • 在这两种情况下,我都无法以错误的语法将您始终获得的running复制为输出。

总之,您不需要使用[ ... ] (或[[ ... ]])构造,因为如果找到正在运行的进程,用于测试的程序已经返回"true“。如果希望将测试建立在pgrep输出的基础上,就需要使用“命令替换”( $(pgrep ...)中的命令替换)(当然还需要将输出重定向移到/dev/null)。

我建议使用shellcheck (也可作为许多Linux发行版上的独立程序)检查您的shell脚本,以防止语法(和一些逻辑上的)错误。

票数 10
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/673712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档