shell – 在NAME之后是否禁止使用分号?为NAME做…?
bash手册列出了for compound语句的语法
名称[[in [word …]]; ]列表; DONE 这意味着如果省略in子句,则do之前的分号是可选的. [笔记2]. 但是,Posix规范仅为for_clause列出以下三个产品: for_clause : For name linebreak do_group | For name linebreak in sequential_sep do_group | For name linebreak in wordlist sequential_sep do_group ; 作为参考,linebreak是NEWLINE的可能空序列,而sequential_sep是分号或NEWLINE,可能后跟NEWLINE序列: newline_list : NEWLINE | newline_list NEWLINE ; linebreak : newline_list | /* empty */ ; separator : separator_op linebreak | newline_list ; sequential_sep : ';' linebreak | newline_list ; 据我所知,这禁止了foo的语法;做:;完成. 在实践中,我尝试的所有shell(bash,dash,ksh和zsh)都接受foo;做:;完成并为foo做:;没有投诉,无论Posix或他们自己的文件[注3]. 这是Posix标准中语法中的意外遗漏,还是在该语法中使用分号是否应被视为标准的(通常实现的)扩展? 附录 在for循环的XCU描述中,Posix似乎坚持使用换行符:
但是,在Rationale卷中,很明显语法是最后一个词:
笔记 >显然这是第一个与shell和language-lawyer配对的SO问题.没有idle-curiosity,这可能更合适.
这清楚地表明,前面的分号可以用换行符替换,但似乎没有提到可以对前面的分号执行相同的转换. ksh手册页将语法列为:
(我相信分号; do和; done代表“分号或换行符”.我找不到任何明确的声明,但这是理解语法描述的唯一方法.) zsh手册显示:
解决方法
很好地发现!我没有明确的答案,但这里是源代码所说的内容:
它在the original Bourne shell的AT& T UNIX v7中确实无效: (shell has just read `for name`): IF skipnl()==INSYM THEN chkword(); t->forlst=item(0); IF wdval!=NL ANDF wdval!=';' THEN synbad(); FI chkpr(wdval); skipnl(); FI chksym(DOSYM|BRSYM); 鉴于此片段,它似乎不是一个有意识的设计决定.这只是分组作为in组的一部分处理的副作用,当没有“in”时,它会被完全跳过. Dash同意它是not valid in Bourne,但是将其添加为扩展名: /* * Newline or semicolon here is optional (but note * that the original Bourne shell only allowed NL). */ Ksh93 claims that it’s valid,但没有说明背景: /* 'for i;do cmd' is valid syntax */ else if(tok==';') while((tok=sh_lex(lexp))==NL); Bash没有评论,但explicitly adds support for this case: for_command: FOR WORD newline_list DO compound_list DONE { $$= make_for_command ($2,add_string_to_list (""$@"",(WORD_LIST *)NULL),$5,word_lineno[word_top]); if (word_top > 0) word_top--; } ... | FOR WORD ';' newline_list DO compound_list DONE { $$= make_for_command ($2,$6,word_lineno[word_top]); if (word_top > 0) word_top--; } 在zsh中,它只是一个side effect of the parser: while (tok == SEPER) zshlex(); 其中(SEPER是 for foo; ; ; ; ; ; ; ; ; do echo cow; done 对我来说,这一切都指向POSIX中的故意遗漏,并作为扩展广泛和有意地支持. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |