我对这个表达有点困惑:
gcc -c -g program.c >& compiler.txt
我知道
&>filename
会将 stdout 和 stderr 重定向到文件 filename
。 但在这种情况下,& 符号位于大于号的之后。 它看起来像 M>&N
的形式,其中 M
和 N
是文件描述符。
在上面的代码片段中,做
M=1
和N='compiler.txt'
吗? 这与以下内容到底有什么不同:
gcc -c -g program.c > compiler.txt (ampersand removed)
我的理解是每个打开的文件都与大于2的文件描述符相关联。这是正确的吗?
如果是,文件名是否可以与其文件描述符互换作为重定向目标?
这与
&>
相同。来自 bash 手册页:
重定向标准输出和标准错误 该结构允许标准输出(文件描述符 1)和 标准错误输出(文件描述符 2)被重定向到 文件名是单词的扩展。
There are two formats for redirecting standard output and standard error: &>word and >&word Of the two forms, the first is preferred. This is semantically equiva- lent to >word 2>&1
&>
vs >&
:首选版本是 &>
(破坏)关于:
&>
>&
两者都会破坏文件 - 在写入文件之前将文件截断为 0 字节,就像
> file
在仅 STDIN 的情况下所做的那样。
bash
手动重定向部分补充说:
这两种形式中,首选第一种。这在语义上等同于
>word 2>&1
使用第二种形式时,word可能不会扩展为数字或
。如果是这样,出于兼容性原因,其他重定向运算符将适用(请参阅下面的复制文件描述符)。-
(注:在
zsh
中都是等价的。)
训练手指使用第一种 (
&>
) 形式是非常好的练习,因为:
&>>
,因为 >>&
不支持 bash
(追加)只有一种附加形式:
附加标准输出和标准错误的格式为:
&>>word
这在语义上等同于
>>word 2>&1
(请参阅下面的复制文件描述符)。
注:
&>
中只有一种追加方式,再次建议使用 >&
而非 bash
。zsh
允许使用 &>>
和 >>&
形式。有点偏离主题,但这就是为什么我一直坚持像
>/dev/null 2>&1
这样的长形式。
对于那些在 cron 之类的事情上向后执行而不在其上添加 >&、&>、>>&、&>>、... 的人来说,这已经足够令人困惑了。
我经常需要在 crontab -l
中添加注释,提醒人们“2>&1 > /dev/null”不是最佳实践。
只要您记住首先给出任何“最终目的地”,那么它应该与使用任何类似 Bourne 的 shell、附加或其他方式的任何 Unix 或类 Unix 系统上的语法相同。 另外,由于
&>
实际上是一种 Bash-ism(可能起源于 csh?不记得了,但它无论如何都不是 POSIX),因此它并不总是在锁定的商业 UNIX 系统上受支持。