为什么有时在元字符周围需要空格?
几个月前,我在我的胳膊上刺了一个叉形炸弹 ,我跳过了空格,因为我觉得没有它们看起来更好。 但令我沮丧的是, 有时 (并非总是)当我在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)(当你得到纹身时,你可能已经充分陶醉了,但是它确实存在) 。 这留下了三个明显的可能性
- 在转录代码时,您没有键入BOM。 其结果是GIGO的一个明显的应用。 shell根本无法识别出现在您的失败转录中的BOM。
- 你的shell太旧了。 它不能识别Unicode字符,所以BOM(也可能是所有其他的Unicode字符)被完全忽略,即使一个文件的开头的任何地方的BOM都被认为是一个零宽度的非破坏性的空间。
- 你的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将{
识别为令牌。