gpt4 book ai didi

bash - bash 中的重复否定 (!) 运算符不会相互否定

转载 作者:行者123 更新时间:2023-11-29 09:01:06 25 4
gpt4 key购买 nike

所以这更像是我遇到的一个奇怪的东西,而不是我真正想要使用的东西。但是我发现了一些我不理解的 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 行,使用正常测试,按我预期的方式运行。单个 bang 不打印一行(因为/tmp 存在),而 double bang 打印一行。

第 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] == '\0'))) {
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;
}

关于bash - bash 中的重复否定 (!) 运算符不会相互否定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49884616/

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