【问题标题】:Redirecting the output of a child process重定向子进程的输出
【发布时间】:2011-12-19 01:33:03
【问题描述】:

有几种方法可以重定向子进程的输出:

  1. 使用freopen(3)
  2. 使用dup(3)
  3. 使用popen(3)
  4. ...

如果只需要执行一个子进程并将其输出保存在给定文件中,应该选择什么,就像ls > files.txt 的工作原理一样?

shell 通常使用什么?

【问题讨论】:

    标签: c shell unix io-redirection


    【解决方案1】:

    你可以通过strace(1)你的shell来发现你最喜欢的shell使用了什么。

    在一个终端中:

    echo $$
    

    在另一个终端:

    strace -o /tmp/shell -f -p [PID from the first shell]
    

    再次进入第一个终端:

    ls > files.txt
    

    在第二个终端中,^C 您的strace(1) 命令,然后编辑/tmp/shell 输出文件以查看它为执行重定向所做的系统调用。


    freopen(3) 操作 C 标准 IO FILE* 指针。所有这些都将在execve(2) 调用的另一端被丢弃,因为它保存在用户内存中。你可以在execve(2) 调用之后使用这个,但是一般使用会很尴尬。

    popen(3) 打开一个单向的pipe(7)。这很有用,但非常有限——您可以得到标准输出描述符标准输入描述符。对于像ls | grep foo | sort 这样的输入和输出都必须重定向的东西,这将失败。所以这是一个糟糕的选择。

    dup2(2) 将管理文件描述符——一种内核实现的资源——因此它将在execve(2) 调用中持续存在并且您可以根据需要设置任意数量的文件描述符,即很适合ls > /tmp/output 2> /tmp/error 或同时处理输入输出:ls | sort | uniq

    还有另一种机制:pty(7) 处理。 forkpty(3)openpty(3) 函数可以管理专门为处理另一个程序而创建的新伪终端设备。 Advanced Programming in the Unix Environment, 2nd edition book 在其源代码中有一个非常好的 pty 示例程序,但如果您无法理解为什么这很有用,请查看 script(1) 程序——它创建了一个新的伪终端并使用它来记录程序的所有输入和输出,并将脚本存储到文件中以供以后回放或记录。您还可以使用它在交互式程序中编写动作脚本,类似于expect(1)

    【讨论】:

      【解决方案2】:

      我希望找到主要使用的dup2()

      popen()freopen() 均未设计用于处理重定向,例如 3>&7。在某种程度上,可以使用dup(),但3>&7 示例显示了dup() 开始吱吱作响的地方;您必须确保文件描述符 4、5 和 6 已打开(而 7 未打开),然后它才能处理 dup2() 的操作。

      【讨论】:

      • 我刚刚根据@sarnold 的建议检查了strace 输出,bash 使用dup2()。所以你似乎是对的! +1
      猜你喜欢
      • 2021-03-25
      • 2013-06-02
      • 1970-01-01
      • 2012-07-04
      • 1970-01-01
      • 2023-04-05
      • 2011-01-10
      • 1970-01-01
      相关资源
      最近更新 更多