bash 的输出重定向 - >> 和 >&、重定向和复制有什么区别?

Chr*_*ian 6 bash io-redirection shell-script

我正在尝试了解输出重定向,但我很挣扎。我不认为我真的明白这些差异。

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?
Run Code Online (Sandbox Code Playgroud)

我假设&符号&表示重复,而不是重定向。但是,什么是重定向的差异ab(将a保持不变?)来复制ab(会ab一样吗?)?2>&1似乎有效地重定向并合并21,即本来会进入的2内容现在是1,但仅限于1...为什么?

我很困惑...

Ste*_*itt 8

首先,或之后的 任何内容都是文件名;所以写入一个名为.>>>> 11

您的示例中给出的其他形式的数字是文件描述符。默认情况下,程序以连接的文件描述符 0(标准输入)、1(标准输出)和 2(标准错误)开始;当您从交互式 shell 启动程序时,这些连接到终端的输入和输出(您可以通过ls -l /proc/$$/fd在 Linux 上运行来查看这些)。

在 之前指定一个数字>>>>&指定您要操作的文件描述符;数字必须在>符号的正前方。因此

echo Example 2> stderr
Run Code Online (Sandbox Code Playgroud)

将打印“示例”并创建一个空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,出于您需要的任何目的重定向标准输出和错误,然后恢复它们...

猛砸手册有所有的细节。