我试图理解输出重定向,但我很挣扎。我认为我并没有真正理解其中的差异。
1 > file # - redirect stdout to file (override mode)
1 >> file # - redirect stdout to file (append mode)
2 > 1 # 1) would that also redirect stderr to stdout, replacing stdout?
2 >> 1 # 2) would this redirect stderr to stdout (appending to it,
# i.e. haivng both sent to stdout?)
1>&9 # - duplicates stdout to file descriptor (pointer) 9
# 3) what's the difference of 2>&1 to a 2 >> 1? Does >> only run at the end
# of output?
echo foo > file # - redirects output to file (override mode)
>file 2>&1 # - duplicates stderr to stdout, then redirects to file in override mode
# 4) why is this giving me stdout, too, when the syntax is 2>&1,
# i.e. duplicate stderr into stdout - not merge 2 into 1?
我假设&符号&
意味着重复,而不是重定向。但是重定向a
到b
(将a
保持不变?)与复制a
到b
(将a
和b
相同吗?)有什么区别?2>&1
似乎有效地重定向并合并2
到1
,即本来应该进入的内容2
现在在1
,但仅在1
...为什么?
我很困惑...
答案1
首先,任何事后 >
或者>>
是文件名; so> 1
写入名为1
.
示例中给出的其他形式的数字是文件描述符。默认情况下,程序以连接的文件描述符0(标准输入)、1(标准输出)和2(标准错误)开始;当您从交互式 shell 启动程序时,这些程序将连接到终端的输入和输出(您可以通过ls -l /proc/$$/fd
在 Linux 上运行来看到这些)。
在 之前指定一个数字>
,>>
或>&
指定您要操作的文件描述符;数字必须位于符号前面>
。因此
echo Example 2> stderr
将打印“示例”并创建一个空stderr
文件(其中包含发送到标准错误的任何内容)。
您可以将文件描述符视为表中的条目,指向文件;因此默认情况下:
- 0分至
/dev/tty
- 1 分 至
/dev/tty
- 2分至
/dev/tty
指定1> file
(或简单地> file
)将文件描述符 1 更新为指向file
,以截断模式打开(因此其内容被替换)。指定2> 1
更新文件描述符 2 以指向1
以截断模式打开的名为 的文件。
>&
使用(或,这是首选形式)复制文件描述符&>
只需更新一个文件描述符以指向另一个文件描述符所指向的任何内容。在最后一个示例中,> file
更新文件描述符 1:
- 0分至
/dev/tty
- 1 分 至
file
- 2分至
/dev/tty
然后2>&1
更新文件描述符2:
- 0分至
/dev/tty
- 1 分 至
file
- 2分至
file
(顺序很重要:> file 2>&1
产生上述内容,2>&1 > file
最终只会重定向文件描述符 1)。
该1>&9
表单仅在文件描述符 9 已打开时才有效,例如通过将文件描述符 1 复制到其中 ( 9>&1
) 或打开文件 ( 9> file
)。这种类型的构造对于在重定向时跟踪文件描述符的原始内容很有用;因此,在脚本中,您可以安全地复制 1 和 2,将标准输出和错误重定向到您需要的任何目的,然后恢复它们...
这bash手册有所有详细信息。
答案2
你有一些错误的假设。
重定向的一般语法是:
[n]redirection-operator word
其中n
是十进制数,表示文件描述符。请注意,n
和之间没有空格redirection-operator
。
要将标准输出重定向到文件,您需要:
> file
或者:
1> file
1 > file
意味着运行命令1
并将其输出重定向到file
,或显式地与以下内容相同:
1 1> file
2> file
标准错误和运算符也是如此>>
。
要复制文件描述符,您将使用:
[n]<&word
用于输入文件描述符[n]>&word
用于输出文件描述符[n]<>word
打开文件描述符进行读写
以上所有内容都是标准语法,如果您将其用于#!/bin/sh
脚本,则它们将起作用。
某些 shell 有自己的扩展,例如bash
用于>&
重定向标准输出和标准错误的 with,ksh93
用于<>;
在命令完成时截断到偏移量。
现在,您可以看到它们的差异。
这复制运算符仅适用于文件描述符,而重定向运算符仅适用于文件(在幕后映射到文件描述符)。