program 2> error.log
program &> filename
program >> filename 2>&1
program 2>&1
我能够弄清楚这几行字的含义。
但是我不太明白应该把空格放在哪里。我还担心把空格放在哪里其实并不重要。谢谢阅读。
答案1
是的,单词和重定向之间的间距无关紧要。这是简短的回答。
细节在于,shell(为了简单起见,我们仅引用bash
)将某些字符和字符组视为“单词”和“元字符”。摘自 bash 4.3 手册:
元字符
不加引号时用于分隔单词的字符。以下之一:
| & ; ( ) < > space tab
和
单词 shell 认为是单个单位的字符序列。也称为标记。
因此,当我们这样做时:
$ echo "hello world">/dev/null
或者
$ echo "hello world" > /dev/null
这仍然是 3 个单词(“hello world” 可以被视为一个 shell 单词,因为它被引号括起来了),带有一个>
元字符和几个空格。Shell 将看到它,并首先执行重定向(因此它首先查找元字符),然后根据其标准行为运行命令。
但是,重定向的顺序非常重要,尤其是当您使用类似 之类的东西复制文件描述符时2>&1
。假设您想将 stderr 和 stdin 发送到同一位置。以下是错误的做法:
$ stat ./non-existent file 2>&1 > /dev/null
stat: cannot stat './non-existent': No such file or directory
stat: cannot stat 'file': No such file or directory
您正在将文件描述符2
输出到与 相同的位置1
,即您的终端,但它已经这样做了。这就是 stderr 出现的原因。
如果你stdout
先重定向,然后再改变2
指向的位置,那么它就会起作用:
$ stat ./non-existent file > /dev/null 2>&1
答案2
除少数特殊情况外,间距并不重要。
- 标准输出重定向前有一个数字。
根据Bash 手册:
如果省略文件描述符编号,并且重定向运算符的第一个字符为 '<',则重定向指向标准输入(文件描述符 0)。如果重定向运算符的第一个字符为 '>',则重定向指向标准输出(文件描述符 1)。
因此,例如,echo test 2 > output.txt
将被解释为echo test 2 1> output.txt
,即将命令的标准输出重定向echo test 2
到文件 output.txt,这将创建包含文本“test 2”的文件。
另一方面,echo test 2> output.txt
将被解释为“将命令的标准输出(文件描述符 2)重定向echo test
到文件 output.txt”,该文件将为空,因为命令的标准输出为空。
此行为不仅限于数字 1 和 2。因此echo test 5> output.txt
还将创建一个空文件。
<(...)
当以或形式使用进程替换时>(...)
,左括号与 > 或 < 之间的空格不允许。
请注意,< 或 > 和左括号之间不能有空格,否则该构造将被解释为重定向。