Bash:if语句总是成功

时间:2017-03-02 14:42:49

标签: linux bash shell if-statement

我有以下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。

我在这里忽略了什么吗?

4 个答案:

答案 0 :(得分:3)

您正试图在[ ... ]>进行数值比较。这不起作用;要将值作为数字进行比较,请改用-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将以真实状态退出,如果不找到则返回false,因此您可以执行此操作:

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

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

另外,如果您要查找的进程名称是文字字符串而不是变量,那么我最喜欢的任务就是修改这个字符串,而不是通过额外的grep -v grep:< / p>

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选项,这样您就可以在没有pidof重定向的情况下使用,但版本是我的在Linux系统上找不到那个选项。)

还有pidof;我还没有遇到pgrep没有if pidof newrelic-daemon >/dev/null; then 的系统,但是如果遇到问题,你可以用同样的方式使用它:

$xmldoc = new DOMDocument();
$xmldoc->load('try.xml');
$root= $xmldoc->documentElement;
$data = $root->getElementsByTagName('Student');
if($data) {
    $domElemsToRemove = [];
    foreach ( $data as $domElement ) {

        $domElemsToRemove[] = $domElement;
    }
    foreach( $domElemsToRemove as $domElement ){
        $domElement->parentNode->removeChild($domElement);
    }


    $xmldoc->save('try.xml');
}

答案 1 :(得分:2)

其他答案为您提供了更多详细信息。我会做你想做的事情:

if pidof newrelic-daemon >/dev/null; then
  echo "New Relic is already running."
fi

甚至

pidof newrelic-daemon >/dev/null && echo "New Relic is already running."

答案 2 :(得分:1)

如果要将整数与test进行比较,则必须使用-gt选项。参见:

man test

man [

答案 3 :(得分:1)

@Stephen:尝试(将[更改为[[到您的代码中以及将完全填写if块的fi:

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