输入重定向到 for 和 while

输入重定向到 for 和 while

只是出于好奇,

该命令的工作原理:

$ <file cat

但这些都没有:

$ <file for
bash: for: command not found...

$ <file while
bash: while: command not found...

这是为什么?

答案1

POSIX语法是这样写的。命令定义为:

command          : simple_command
                 | compound_command
                 | compound_command redirect_list
                 | function_definition

一个简单的命令在哪里

simple_command   : cmd_prefix cmd_word cmd_suffix
                 [...]

两者cmd_prefix最终cmd_suffix都允许重定向。对于复合命令,只有redirect_list末尾允许它们,前面没有任何允许它的命令。

不完全是这样像这样,例如 Zsh 接受这个就好了:

% > output for x in a b c ; do echo $x; done
% cat output 
a
b
c

但这是 Zsh 不兼容的,因为在标准 shell 中,前导重定向强制命令for被解析为常规简单命令,这意味着以下是有效的shell 将尝试查找并运行一个字面上称为的命令for(带有五个参数,并且 stdout 重定向)。给出您看到的错误:

$ > output for x in a b c
bash: for: command not found

(特别是在 Bash 中,首先解析整个输入行,因此,如果您将for-do-done第一个示例中的整个内容提供给 Bash,它只会删除 , 的语法错误do,并且不会执行for之前的 。)

如果我不得不猜测,我预计该定义的根本原因是它总是这样工作,因此标准已将其编码为这样。

尽管请注意,已经有讨论关于改变这方面的标准。 (可能没有一个头脑正常的人实际上依赖于> output for ...调用命令的含义for而不是 shell 循环)。

答案2

forwhile不是命令,它们是启动循环头的保留字。您可以对整个循环使用重定向,但必须在最后。

这确实不是工作:

<file for((i=0;i<3;i++)); do read line; echo "$line"; done

工作:

      for((i=0;i<3;i++)); do read line; echo "$line"; done <file

相关内容