将标准输出和标准错误重定向到文件的符合 POSIX 的方法

Exe*_*ork 13 shell io-redirection posix stdout stderr

我正在尝试编写一个符合 POSIX 标准的脚本,因此它可以在任何 *nix 系统(Debian、Fedora、CentOS、AIX、Arch……所有这些)上运行。说到重定向,我对 POSIX 支持什么和不支持什么感到很困惑。

如果我重定向ls -l file missingfile &> out.txt这在bash. 不存在的stderr抱怨行missingfile和 , 的权限输出file都在out.txt. 但是,我相信这只是有效,因为这些 shell 支持的不仅仅是 POSIX 标准运算符。在研究这个问题时,我遇到了相互矛盾的答案。

这stackexchange答案,例如,似乎在暗示&>>&>>&&>>是非标准操作。但是,此答案明确指出some-program > some_file 2>&1符合 POSIX。这是否意味着>&运算符(使用数字表示stderr& stdout)符合 POSIX 而&>用于自动重定向stderr和重定向stdout到文件符合 POSIX 标准?或者都是&>>&不符合POSIX / POSIX兼容的(这两人一个是错的)?

我考虑过完全避免使用该&标志并使用,ls -l file missingfile >out.txt 2>out.txt但这有其自身的问题。以ls这种方式运行命令会导致 shell 打开 的两个文件句柄out.txt,它们都指向文件中的偏移量 0。因此,当ls查找这两个文件时,其中一个消息被破坏了。

什么人会期望ls -l file missingfile >out.txt 2>out.txt输出:

-rw-r--r-- 1 blah blah 0 Jun  3 13:18 file
ls: cannot access 'missingfile': No such file or directory
Run Code Online (Sandbox Code Playgroud)

实际输出是什么:

-rw-r--r-- 1 blah blah 0 Jun  3 13:18 file
le or directory
Run Code Online (Sandbox Code Playgroud)

以符合 POSIX 的方式重定向stdout和重定向stderr到文件的最佳方法是什么?

Gil*_*il' 31

您可以查看POSIX 规范。这种语言并不总是很容易理解,但如果您知道自己在寻找什么,就可以知道它是否存在。

POSIX 包括重定向操作,其中N是可选的文件描述符编号(输入默认为 0,输出默认为 1),可以是:N>&wordN<&word

  • 一个数字序列,将文件描述符N重定向到已经在word 上打开的任何内容。
  • 字符-,收文件描述符ñ

所以,>out.txt 2>&1是一个符合POSIX标准的方式来标准输出和标准错误重定向到out.txt。它也适用于 POSIX 之前的Bourne shell

>& 后跟文件名是某些 shell(包括 bash)中的扩展名,它将 stdout 和 stderr 都重定向到该文件。

&>>&bash(和 zsh)中后跟文件名的同义词。它的工作即使文件名是数字序列或优势-(例如foo >&"$a"相当于foo 1>&3 2>&1如果值a是数字3,但foo >myfile 2>&1如果价值amyfile)。它的缺点是它与 POSIX 不兼容。在符合 POSIX 的 shell 中,echo foo &>bar被解析为命令echo foo&操作符和命令>bar:打印的后台进程foo和创建或清空文件的前台进程bar