Sta*_*mar 4 bash shell-script shell-builtin
只是出于好奇,
此命令有效:
$ <file cat
Run Code Online (Sandbox Code Playgroud)
但这些都没有:
$ <file for
bash: for: command not found...
$ <file while
bash: while: command not found...
Run Code Online (Sandbox Code Playgroud)
这是为什么?
该POSIX语法写的方式。命令定义为:
command : simple_command
| compound_command
| compound_command redirect_list
| function_definition
Run Code Online (Sandbox Code Playgroud)
一个简单的命令在哪里
simple_command : cmd_prefix cmd_word cmd_suffix
[...]
Run Code Online (Sandbox Code Playgroud)
和两者cmd_prefix
并cmd_suffix
最终允许重定向。对于复合命令,只有redirect_list
最后允许它们,没有任何东西允许它在前面。
它不完全具备是这样的,比如岩组接受这个就好了:
% > output for x in a b c ; do echo $x; done
% cat output
a
b
c
Run Code Online (Sandbox Code Playgroud)
但这是 Zsh 不兼容的,因为在标准 shell 中,前导重定向强制for
命令被解析为常规的简单命令,这意味着以下内容是有效的,并且 shell 将尝试查找并运行字面上调用的命令for
(带有五个参数,以及标准输出重定向)。给出你看到的错误:
$ > output for x in a b c
bash: for: command not found
Run Code Online (Sandbox Code Playgroud)
(特别是在 Bash 中,首先解析整个输入行,因此如果您for-do-done
将第一个示例中的整个 Bash放在一行中,它只会丢弃 的语法错误do
,并且不会在此for
之前执行。)
如果我不得不猜测,我希望定义的根本原因是它总是这样工作,所以标准已经这样编纂了它。
但请注意,已经讨论过在这方面更改标准。(可能没有人在他们的正常头脑中实际上依赖于> output for ...
调用命令for
而不是 shell 循环的含义)。
for
并且while
不是命令,它们是开始循环头的保留字。您可以在整个循环中使用重定向,但必须在最后。
这并不能正常工作:
<file for((i=0;i<3;i++)); do read line; echo "$line"; done
Run Code Online (Sandbox Code Playgroud)
这确实有效:
for((i=0;i<3;i++)); do read line; echo "$line"; done <file
Run Code Online (Sandbox Code Playgroud)