bash扩展测试语法中的重复否定(!)运算符不会互相否定?
所以这比我真正想要使用的东西更加奇怪.但我发现了一些我用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:
哪个提示使用了!保留字. 但是,这并不能很好地解释它.所以我看了一下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; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |