几个月前,我在手臂上纹了一个fork bomb,我跳过了空白,因为我觉得没有它们看起来更好。但令我沮丧的是,有时(并不总是)当我在shell中运行它时它不会启动一个fork炸弹,但它只是给出了一个语法错误。
bash: syntax error near unexpected token `{:'
昨天它发生在我尝试在朋友的Bash shell中运行它,然后我添加了空格,它突然起作用,:(){ :|:& };:
而不是:(){:|:&};:
空白是否重要;我的胳膊上有语法错误吗?!
似乎总是在zsh中工作,但在Bash中却不起作用。
A related question没有解释任何有关空白的内容,这实际上是我的问题; 为什么Bash需要的空白才能正确解析它?
答案 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&}
不是
你实际上需要这样的纹身: p>
来自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)(当你得到你没注意到它的纹身时,你可能已经充分陶醉了,但它是真的在那里)。这留下了三个明显的可能性: