这个 shell 命令是什么意思?

What is the meaning of this shell command?

我目前正在学习 Shell 表示法,我 运行 通过以下命令:

./a.out < infile 2>&1 > outfile

其中 infile 和 outfile 是文件名。

我认为这个命令的作用是

  1. 将“标准输入”设置为“infile”
  2. 将“标准错误”重定向到“标准输出”
  3. 将“标准输出”设置为“outfile”

我的解释正确吗?如果不是,我应该如何理解这个命令?

TL;DR: 2>&1 到最后 .

你的解释是正确的。但是这个命令有问题。让我们看一下您列出的步骤并列出所有血淋淋的细节。

  1. < infileinfile 重定向标准输入。这意味着当 ./a.out 从标准输入读取时,它将从文件中读取。

  2. 2>&1 将 stderr 重定向到 stdout 当前指向的任何地方。通常 stdout 将是终端,因此这使得 stderr 也写入终端。但是 stderr 通常默认写入终端,所以这可能是一个错误。我将在下面进一步解释。

  3. > outfile 将标准输出重定向到 outfile。当 ./a.out 写入标准输出时,它将写入文件。

最终效果是程序从 infile 读取,将其标准输出写入 outfile,并将错误写入终端。

如果您仔细按照这些步骤进行操作,您可能会对第 2 步感到困惑,因为 2>&1 最终将 stderr 重定向到它已经指向的位置。很可能写这篇文章的人混淆了重定向的顺序并且打算写这个:

# Fixed redirection order.
./a.out < infile > outfile 2>&1

这里第 2 步和第 3 步互换了。

  1. > outfile 将标准输出重定向到 outfile。当 ./a.out 写入标准输出时,它将写入文件。 这里没有变化。

  2. 2>&1 将 stderr 重定向到 stdout 当前指向的任何地方,outfile。所有输出现在都重定向到 outfile.

在此版本中,stdout 和 stderr 都被重定向到 outfile。一切都被捕获,包括常规输出和错误。这可能就是我们的意图,同意吗?

如果你以前没有看过这个,它可能会向后看。为什么 2>&1 在最后?关键的见解是,当我们说 2>&1“将 stderr 重定向到 stdout”时,我们并不是说 stderr 现在和永远指向 stdout。我们的意思是 stderr 将指向 stdout currently 指向的任何地方。如果我们将 stderr 重定向到 stdout,然后将 stdout 重定向到其他地方,stderr 会继续指向之前的位置。

这就是 2>&1 放在最后的原因。