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

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

bash: syntax error near unexpected token `{:' 

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

空白是否重要? 我在arm上纹了一个语法错误?!

它似乎总是工作在zsh ,但不是在Bash。

一个相关的问题没有解释任何关于空格的问题,这实际上是我的问题。 为什么Bash需要空白才能正确parsing它?

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

因为&是元字符,所以在之前省略第二个空格。 因此,你的纹身应至less有一个空格字符。

 :(){ :|:&};: 

只是纹身一个

 #!/bin/zsh 

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

大括号比特殊符号更像奇怪的关键字,并且确实需要空格。 例如,这与圆括号不同。 比较:

 (ls) 

哪个工作,并且:

 {ls} 

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

 { ls; } 

分号停止将大括号作为ls的参数。

你所要做的就是告诉人们你正在使用比例字体,而且字体空间很窄。

尽pipe在纹身字体中不容易看到,但是在大括号和冒号之间实际上有一个字节顺序标记(BOM)(当你得到纹身时,你可能已经充分陶醉了,但是它确实存在) 。 这留下了三个明显的可能性

  1. 在转录代码时,您没有键入BOM。 其结果是GIGO的一个明显的应用。 shell根本无法识别出现在您的失败转录中的BOM。
  2. 你的shell太旧了。 它不能识别Unicode字符,所以BOM(也可能是所有其他的Unicode字符)被完全忽略,即使一个文件的开头的任何地方的BOM都被认为是一个零宽度的非破坏性的空间。
  3. 你的shell太新了。 使用物料清单作为ZWNBS已被弃用,作者已经实现了将来不再允许这种用法的Unicode版本。

然后我添加了空白,它突然工作…

这是因为shell是如何parsing的。 在函数定义开始之后,即在{之后,需要一个空格。

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

是有效的。 另一方面,

 foo() {echo hey&} 

不是。


你其实需要这样的纹身:

在这里输入图像说明


来源 :

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

{使{echo被解释为单个标记。


等同的forms

 :(){ :|:& };: 

将会

 :(){ :|:& };: 

请注意, {在替代版本中没有空格,但换行会导致shell将{识别为令牌。