如何获取 stdin stdout 和 stderr 以外的文件描述符(执行 $ program 1>file_1 3>file_2 之类的操作)?

mox*_*mox 6 shell io-redirection

当可执行文件产生输出时,我更喜欢让可执行文件打印输出stdout,以便将它们重定向到文件中,并将它们通过管道传输到另一个命令。

假设一个可执行文件必须写入两个不同的输出,通常重定向到两个不同的文件。我想避免将文件名传递给可执行文件并直接写入文件,而是我想写一些类似的东西

$ program 1>file_1 3>file_2
Run Code Online (Sandbox Code Playgroud)

有可能做这样的事情吗?

Gil*_*il' 11

你可以,但这不是一个好主意。通常程序以打开的三个文件描述符开始:

  • 0 是标准输入,其中以某种方式处理文本的命令读取不是来自文件的输入。
  • 1 是标准输出,用于命令生成的正常数据,如果数据未明确发送到文件。
  • 2 是标准错误,用于不属于命令生成的有用数据的一部分的诊断消息。

您可以违反这些约定并使用更多文件描述符,但这意味着您的应用程序只能在调用者指定了正确文件描述符的环境中直接使用。您将无法轻松地在您的应用程序中测试它:由于文件描述符 3 及更高版本不受监管,它们可能会在您的应用程序启动时关闭(可以检测到),或者它们可能出于某些不相关的目的而打开(这无法检测到)。

在命令行上传递文件名是指定多个输入或输出文件的正常方式。

话虽如此,要访问任意文件描述符:

  • 在 shell 中:重定向到所需的号码,例如

    IFS= read -r line <&3
    printf "%s\n" "$line" >&4
    
    Run Code Online (Sandbox Code Playgroud)
  • 在 C 中,使用您想要的任何 fd调用readwrite,或调用fdopen以获取 stdio 流。
  • 在 Perl 中,指定 shell 重定向作为要打开的文件名以复制文件描述符,或添加=以执行普通的fdopen.

    open IN3, "<&=3";
    open OUT4, ">&=4";
    
    Run Code Online (Sandbox Code Playgroud)
  • 在 Python 中,调用os.fdopen.