管道旁边的空间

Emm*_*maV 18 shell bash pipe

我见过history | grep blah和history |grep blah; 并且history|grep blah也有效,尽管似乎从来没有人使用过它。

空格中是否有任何意义(例如,与不同命令之间的管道传输需要不同的空格使用),还是总是任意的?

Joh*_*024 23

bash定义了几个元字符。来自man bash:

元
字符 未加引号时用于分隔单词的字符。以下之一:
| &; ( ) < > 空格制表符

因为元字符分隔单词,所以它们是否被空格包围并不重要。管道符号|是一个元字符,因此,正如您所注意到的,它周围不需要空格。

需要注意的是[,],{,},和=是不是元字符。相比之下,它们的含义在很大程度上取决于它们是否被空格包围。

何时需要和不需要空格的示例

正如您所注意到的,是否|被空格包围并不重要。让我们考虑一些通常会使 bash 用户感到困惑的示例。考虑:

$ (date)
Sun Mar  1 12:47:07 PST 2015
Run Code Online (Sandbox Code Playgroud)

上面的括号强制date命令在子shell中运行。因为(和)是元字符,所以不需要空格。相比之下:

$ {date}
bash: {date}: command not found
Run Code Online (Sandbox Code Playgroud)

由于{和}是不是元字符,shell对{date}作为一个词。它不是查找date命令,而是查找名为{date}. 因为它没有找到,所以会产生错误。

另一个常见问题是test命令。以下工作成功:

$ [ abc ] && echo Yes
Yes
Run Code Online (Sandbox Code Playgroud)

去掉空格,出现错误:

$ [abc] && echo Yes
bash: [abc]: command not found
Run Code Online (Sandbox Code Playgroud)

因为[和]都是不元字符,壳对待[.bashrc]作为单个字,结果,就像在date例如,是错误的。

赋值语句也对空格敏感。以下赋值成功:

$ v=date
$ echo $v
date
Run Code Online (Sandbox Code Playgroud)

添加一个空格,赋值失败:

$ v= date
Sun Mar  1 12:55:05 PST 2015
Run Code Online (Sandbox Code Playgroud)

上面的shell临时设置v为空,然后执行date命令。

在之前添加空格=也会导致失败,但原因不同:

$ v =date
bash: v: command not found
Run Code Online (Sandbox Code Playgroud)

在这里,shell 尝试v使用参数执行命令=date。错误是因为它没有找到名为v.

  • 我最近成为了赋值语句的受害者。我在“=”之前和之后都有空格。花了一段时间调试。 (2认同)

ale*_*ail 5

在一种情况下,不使用空格可能会很有用。\n如果您不使用美国布局,您可能会被迫使用一些组合,例如 AltShiftL输入管道。虽然这本身不是问题,但一个后果是有时您还在该字符之前或之后输入非打印字符。例如,在法文 Macbook Pro 键盘上,我必须使用AltShiftL输入|. 当您快速输入时,您可能会意外输入以下内容AltShift:( L, Space)

\n\n
$ sudo dmesg |\xc2\xa0tail\nzsh: command not found: \xc2\xa0tail\n\necho "sudo dmesg |\xc2\xa0tail" | od -a\n0000000    s   u   d   o  sp   d   m   e   s   g  sp   |   \xef\xbf\xbd   \xef\xbf\xbd   t   a\n0000020    i   l  nl\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您不知道AltShiftSpace输入了不同的空格(不间断空格 ( U+00A0 )),则以下错误可能难以理解:zsh: command not found: \xc2\xa0tail

\n