加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash扩展测试语法中的重复否定(!)运算符不会互相否定?

发布时间:2020-12-15 22:55:37 所属栏目:安全 来源:网络整理
导读:所以这比我真正想要使用的东西更加奇怪.但我发现了一些我用bash扩展测试语法无法理解的东西. 检查一下(包括我的shell版本以防万一): 34$SHELL --versionGNU bash,version 3.2.57(1)-release (x86_64-apple-darwin16)Copyright (C) 2007 Free Software Found
所以这比我真正想要使用的东西更加奇怪.但我发现了一些我用bash扩展测试语法无法理解的东西.

检查一下(包括我的shell版本以防万一):

34>$SHELL --version
GNU bash,version 3.2.57(1)-release (x86_64-apple-darwin16)
Copyright (C) 2007 Free Software Foundation,Inc.
35>[ ! -d /tmp ] && echo Hi
36>[ ! ! -d /tmp ] && echo Hi
Hi
37>[[ ! -d /tmp ]] && echo Hi
38>[[ ! ! -d /tmp ]] && echo Hi
39>

好的,所以第35和36行使用正常测试,按照我的预期运行.单个爆炸不会打印一条线(因为/ tmp存在),双重爆炸.

第37行,使用扩展的bash语法,也没有打印任何东西,正如我所料.但第38行也没有!这对我来说是令人惊讶的;它表示该目录不存在,但也不存在?

搜索有关这方面的信息令人沮丧.我在这里错过了什么吗?一个未提及的语法错误?我只是想明白为什么会这样.

解决方法

由于在BASH代码中使用了一个在这种特殊情况下没有切换的标志,只有第一个实例!重要的是,除非括号将它们分开.

为了找到这个,首先我看一下Bash(1) Man Page:

Reserved Words

Reserved words are words that have a special meaning to the shell. […] words are recognized as reserved when unquoted and either the first word of a simple command (see SHELL GRAMMAR below) or the third word of a case or for command

哪个提示使用了!保留字.

但是,这并不能很好地解释它.所以我看了一下source code (version 4.4.18) for Bash.

它看起来像command.h包含一个为命令设置的标志,当它检测到!符号:

#define CMD_INVERT_RETURN  0x04 /* Invert the exit value. */

这在execute_cmd.c文件中多次使用:

invert = (command->flags & CMD_INVERT_RETURN) != 0;

但是这个文件似乎只是检查是否存在该标志.我相信它的解析是在另一个文件中完成的.

在parse.y的第4507行,我们可以看到它似乎只是设置,而不是切换.这意味着BANG(!)的出现次数无关紧要,它只会设置一次标志.

else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == ''))) {
  if (tok == WORD)
dispose_word (yylval.word); /* not needed */
  term = cond_term ();
  if (term)
term->flags |= CMD_INVERT_RETURN;
}

我发现这种行为很奇怪,因为稍后在代码中,支持在parse.y的第1201行切换此值,该行与管道相关(为便于阅读而格式化)

pipeline_command: pipeline
{ $$= $1; }            
    | BANG pipeline_command {
        if ($2)
            $2->flags ^= CMD_INVERT_RETURN; /* toggle */
        $$= $2;
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读