我见过history | grep blah
并且history |grep blah
;并且history|grep blah
也有效,尽管似乎没有人使用过它。
空格是否有任何意义(例如,不同命令的管道传输需要不同的空格使用),或者它总是任意的?
答案1
bash
定义了几个元字符。从man bash
:
元字符
当不加引号时,用于分隔单词的字符。以下之一:
| &; ( ) < > 空格制表符
因为元字符分隔单词,所以它们是否被空格包围并不重要。管道符号|
是一个元字符,因此,正如您所注意到的,它周围不需要空格。
请注意[
,]
、{
、}
、 和=
是不是元字符。相比之下,它们的含义在很大程度上取决于它们是否被空格包围。
何时需要和不需要空格的示例
|
正如您所注意到的,是否被空间包围并不重要。让我们考虑一些经常让 bash 用户感到困惑的例子。考虑:
$ (date)
Sun Mar 1 12:47:07 PST 2015
上面的括号强制date
命令在子 shell 中运行。因为(
和)
是元字符,所以不需要空格。相比之下:
$ {date}
bash: {date}: command not found
因为{
和}
是不是元字符,shell 将其{date}
视为一个单词。它不查找date
命令,而是查找名为 的命令{date}
。因为找不到,所以会出现错误。
另一个常见问题是test
命令。成功运行如下:
$ [ abc ] && echo Yes
Yes
去掉空格,出现错误:
$ [abc] && echo Yes
bash: [abc]: command not found
因为[
和]
是不是元字符,shell 将其[.bashrc]
视为单个单词,结果(就像示例中一样date
)是一个错误。
赋值语句也对空格敏感。如下所示,赋值成功:
$ v=date
$ echo $v
date
添加一个空格,赋值失败:
$ v= date
Sun Mar 1 12:55:05 PST 2015
上面,shell暂时设置v
为空,然后执行date
命令。
在前面添加空格=
也会导致失败,但原因不同:
$ v =date
bash: v: command not found
在这里,shell 尝试使用v
参数执行命令=date
。该错误是因为它找不到名为 的命令v
。
答案2
在一种情况下,不使用空格可能会很有用。如果您不使用美国布局,您可能被迫使用一些组合,例如 AltShiftL输入管道。虽然这本身不是问题,但一个后果是有时您还在该字符之前或之后输入非打印字符。例如,在法文 Macbook Pro 键盘上,我必须使用AltShiftL来输入|
.当您快速输入时,您可能会意外输入以下内容AltShift:( L, Space)
$ sudo dmesg | tail
zsh: command not found: tail
echo "sudo dmesg | tail" | od -a
0000000 s u d o sp d m e s g sp | � � t a
0000020 i l nl
如果您不知道AltShiftSpace输入了不同的空格(不间断空格(U+00A0)),下面的错误可能很难理解:zsh: command not found: tail
答案3
管道让您使用一个程序的输出作为另一个程序的输入......
就 space 而言,这只是可读性/人员偏好的问题,就像 @jasonwryan 提到的那样。
“|”前后各一个空格键是常态....
您还可以将它与 column -t 一起使用,不仅使您的一行整洁,而且使您的输出整洁。
lnydex99uhc:depot_r user$ lsof | grep my | column -t
Microsoft 290 user txt REG 1,4 9515016 170972 /Library/Fonts/PCmyoungjo.ttf
bash 359 user cwd DIR 1,4 714 12246074 /Users/zatef/hw2/base/active/myapp
答案4
在这种情况下,空间的唯一意义是美学。
或者换句话说,可以使命令更易于人类阅读。