如何将单个文件描述符上的读取和写入发送到不同的地方?

Jay*_*Jay 7 io-redirection file-descriptors

我有一个 Linux 可执行文件foo,它从 fd 0 读取输入并将输出写入 fd 0(不是fd 1)。这适用于终端中的交互式使用。

从 shell 命令行,我如何执行这个程序,以便从 fd 0 读取来自一个文件,但写入 fd 0 进入另一个文件?

我能想到的最好的方法是一些帮助程序$ goo input.txt output.txt | foo在哪里goo,但我不知道任何现有的帮助程序,我什至不知道设置的管道|是否是双向的。

Sté*_*las 6

使用socat(版本 2 或更高版本):

socat 'system:cat input.txt & cat > output.txt,commtype=socketpair' \
      'system:foo,nofork'
Run Code Online (Sandbox Code Playgroud)

或者甚至更好:

socat 'CREATE:output.txt%OPEN:input.txt' 'system:foo,commtype=socketpair'
Run Code Online (Sandbox Code Playgroud)

我们使用的socketpair是双向的(管道在 Linux 上不是双向的)。另一种选择是使用上面的伪终端(也是双向的)commtype=pty。如果foo希望与终端交谈,那可能是更好的方法。

或者,您可以使用以下socketpair方法实施该方法perl

perl -MSocket -e '
  socketpair(A, B, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
  if (fork) {
    close A;
    if (fork) {
      open STDOUT, ">&B";
      exec("cat", "input.txt")
    }
    open STDIN, "<&B";
    open STDOUT, ">output.txt";
    exec("cat")
  }
  close B;
  open STDIN, "<&A";
  exec "foo"'
Run Code Online (Sandbox Code Playgroud)

(这里作为一个快速的概念验证,您可能希望添加错误检查并通过不使用那么多进程并避免执行来提高效率cat)。