为什么元字符周围有时需要空格?

时间:2014-01-17 13:03:05

标签: bash shell syntax syntax-error

几个月前,我在手臂上纹了一个fork bomb,我跳过了空白,因为我觉得没有它们看起来更好。但令我沮丧的是,有时(并不总是)当我在shell中运行它时它不会启动一个fork炸弹,但它只是给出了一个语法错误。

bash: syntax error near unexpected token `{:'

昨天它发生在我尝试在朋友的Bash shell中运行它,然后我添加了空格,它突然起作用,:(){ :|:& };:而不是:(){:|:&};:

空白是否重要;我的胳膊上有语法错误吗?!

似乎总是在zsh中工作,但在Bash中却不起作用。

A related question没有解释任何有关空白的内容,这实际上是我的问题; 为什么Bash需要的空白才能正确解析它?

5 个答案:

答案 0 :(得分:266)

在BASH中有一个用于分隔标记的字符列表。这些字符称为元字符,它们是|&;()<>空间标签。另一方面,花括号({})只是构成单词的普通字符。

}之前省略第二个空格,因为&是一个元字符。因此,您的纹身应该至少有一个空格字符。

:(){ :|:&};:

答案 1 :(得分:78)

只是纹身

#!/bin/zsh

shebang在它之上,你会没事的。

答案 2 :(得分:50)

大括号更像奇数关键字而不是特殊符号,并且需要空格。例如,这与括号不同。比较:

(ls)

有效,并且:

{ls}

查找名为{ls}的命令。要工作,必须是:

{ ls; }

分号会将结束括号作为ls的参数停止。

您所要做的就是告诉别人您使用的是具有相当狭窄空格字符的比例字体。

答案 3 :(得分:40)

  

然后我添加了空格,它突然起作用了......

这是因为shell解析了。在函数定义开始后,即在{之后需要一个空格。

foo() { echo hey& }
foo() { echo hey&}
foo(){ echo hey&}

有效。另一方面,

foo() {echo hey&}

不是


你实际上需要这样的纹身:

enter image description here


来自source

  /* We ignore an open brace surrounded by whitespace, and also
     an open brace followed immediately by a close brace preceded
     by whitespace.  */

{之后省略空格会导致{echo被解释为单个标记。


的等效形式
:(){ :|:& };:

将是

:(){
:|:& };:

请注意,备用版本中{之后没有空格,但换行符会导致shell将{识别为令牌。

答案 4 :(得分:40)

虽然在纹身字体中不容易看到,但在支架和冒号之间实际上有一个字节顺序标记(BOM)(当你得到你没注意到它的纹身时,你可能已经充分陶醉了,但它是真的在那里)。这留下了三个明显的可能性:

  1. 转录代码时,您无法输入BOM。结果是GIGO的明显应用。 shell根本无法识别失败转录中不存在的BOM。
  2. 你的外壳太旧了。它无法识别Unicode字符,因此BOM(以及可能是所有其他Unicode字符)被完全忽略,即使文件开头的任何地方的BOM都应被视为零宽度,不间断的空间
  3. 你的shell太新了。不推荐使用BOM作为ZWNBS,作者已经实现了Unicode的未来版本,不再允许使用此版本。