【发布时间】:2017-08-31 22:19:12
【问题描述】:
这篇引人入胜的帖子:
How is this command legal ? “> file1 < file2 cat”
在看似格式错误的cat 调用“shell”(Linux shell,可能是 BASH)中突出显示了令人惊讶的行为。基本上,shell 似乎能够从一系列字符串中不明确的位置抓取可执行文件,然后使用 I/O 重定向到流/文件描述符。
我理解的基本流程是:
- 寻找重定向模式和read them into or out of appropriate streams / file descriptors(例如:
1>(stdout))(这发生在命令中启动可执行进程之前!(例如cat调用)) - 在字符串列表中查找可执行进程。
- 启动那个可执行进程
- 暂停处理完成或继续(根据需要)在步骤 1 中检测到的基于类型的输出。
这导致了一些令人惊讶的逻辑。例如在执行echo "dog" > cat后的新目录中:
<cat cat >dog:使用shell工具cat将“狗”从文件cat写入dog<cat cat> cat cat:覆盖第一个命令,留下一个空白的cat文件(不确定在第二个命令中间会发生什么)。<cat cat> cat cat >dog 2>more:创建空文件dog和more,用空文件覆盖cat文件。<cat >dog cat cat <dog >cat(创建空文件dog,用空文件覆盖cat)-
<cat cat >dog 2>much 1>more:用空文件覆盖cat;创建文件dog/more,每个文件都包含字符串“dog”,创建空much
(以上列表行为已在BASH (v4.3.46) 上测试。)
现在在某个时候,可怜的外壳决定它已经受够了。例如,当遇到:
<cat dog> cat cat >dog >cat
它抱怨:
bash: dog: 找不到命令
但还有一个额外的惊喜 - 该命令实际上已部分完成。与上述大多数示例一样,它用空白文件覆盖文件cat,并创建了一个空白文件dog。
为了更好地理解“most popular Linux shells”和 CMD(标准 Windows shell)中复杂的 I/O 重定向处理:
-
BASH(Linux) -
TCSH(Linux) -
KSH(Linux) -
ZSH(Linux) -
CMD(Windows)
...是这种order-ambiguous I/O重定向解析...
- 都支持? (我只有时间测试
BASH(Linux)和cmd(Windows)。) - 它支持所有受支持的可执行文件还是仅支持核心 shell 实用程序?
- 这些 shell 使用哪些规则来处理流/描述符的清理/排序,特别是在解析基于子字符串的选择而重定向显得不明确的命令时(例如,
stuff.dat>1test.dat<2test.dat其中1test.dat和@987654360 @ 是文件) - shell 之间的解析规则在多大程度上是一致的?
- 是什么决定了这些 shell 中具有复杂 I/O 重定向模式的命令失败?
【问题讨论】:
-
关于 Windows
cmd: cmd.exe redirection operators order and position
标签: bash shell parsing cmd io-redirection