Bash shell 中的事件顺序将标准输出和错误重定向到同一文件

Order of events in Bash shell redirection of standard output and error to the same file

我想问一个关于使用 Bash Shell.

将标准输出和错误重定向到同一个文件的问题

我是 Linux 命令提示符的初学者,正在阅读 William E. Shotts 的一本名为“Linux 命令行”的书。小

在重定向部分,他说要将标准输出和错误重定向到同一个文件,写了以下命令:

ls -l /bin/usr > ls-output.txt 2>&1

据我了解,/bin/usr 目录不存在,因此抛出错误并发送到标准错误文件。命令 ls -l /bin/usr 的输出被重定向到文本文件 ls-output.txt 并且标准错误被重定向到带有 2>&1.

的标准输出

我在两个方面感到困惑:

  1. 首先,事件的顺序。根据我的直觉,因为我认为命令是以 L-R 方式(从左到右)执行的,所以 ls 命令的重定向似乎在标准重定向之前首先朝向 ls-output.txt错误流 (2) 到标准输出流 (1).

  2. 使用了ampersand。我从Google搜索中了解到,如果将&放在命令的末尾,则意味着可以在执行初始命令之前输入其他命令-在初始命令耦合时具有应用程序带定时器。我相信这里的符号意味着 & 意味着我们正在重定向到文件 descriptor 而不是名为 1 的文件名,尽管我不确定这是否正确。

总的来说,我有两个问题:

  1. 上面命令的执行顺序是什么?
  2. 我对符号 & 的功能是否正确?如果不是,它有什么作用?

Linux 具有三个默认数据流 - stdin (0)stdout (1)stderr (2).

  • stdin,或“标准输入”,用于从用户读取数据。
  • stdout,或“标准输出”,用于“正常”输出。
  • stderr,或“标准错误”用于错误。

字符 > 允许您将命令的输出重定向到上述流之一或文件中。

当您 运行 命令 ls -l /bin/usr > ls-output.txt 2>&1 时,您实际上向系统询问了两件事:

  1. 将命令的 stdout 重定向到文件 ls-output.txt.
  2. 将命令的stderr重定向到编号为1的数据流中,即stdout

实际上,单独使用 > 等同于 1>,这意味着您重定向了数据流 1 的所有输出。 1.

& 字符告诉您的系统您要将输出重定向到数据流,而不是文件。省略此字符将导致您的 stderr 写入名为 1.

的文件

重要的是要注意字符 & 在 Linux 中有更多的作用,例如 运行 在后台执行命令或连接命令(使用 &&) ,却完全不同。

此致。

让我详细谈谈方面 1,即事件的顺序。认为事情按照严格的 left-to-right 顺序发生是错误的;命令处理和执行发生在 阶段 并且每个阶段(通常)完成 left-to-right,每个阶段将(再次,通常)在下一阶段开始之前完成。

在这种情况下,相关阶段是:

  1. shell解析命令行(这实际上是本身)。
  2. shell 处理 I/O 重定向(从左到右)。
  3. shell 执行命令(所有重定向都已到位)。

这样做的一个重要后果是您 can't redirect output back to a file you're using as input for the command。例如,如果您尝试使用 sort file.txt >file.txt 对文件进行排序,shell 将打开 file.txt 并清空它以准备好接收新内容sort 有机会读取它之前。结果:一个空文件。

一个不太重要的后果是,如果重定向中出现错误,它甚至会阻止命令启动。如果你 运行 nosuchcommand <nosuchfile,bash 会在它注意到 nosuchcommand 也不存在之前打印出关于 nosuchfile 不存在的错误。