【发布时间】:2011-12-19 01:33:03
【问题描述】:
有几种方法可以重定向子进程的输出:
- 使用
freopen(3) - 使用
dup(3) - 使用
popen(3) - ...
如果只需要执行一个子进程并将其输出保存在给定文件中,应该选择什么,就像ls > files.txt 的工作原理一样?
shell 通常使用什么?
【问题讨论】:
标签: c shell unix io-redirection
有几种方法可以重定向子进程的输出:
freopen(3)
dup(3)
popen(3)
如果只需要执行一个子进程并将其输出保存在给定文件中,应该选择什么,就像ls > files.txt 的工作原理一样?
shell 通常使用什么?
【问题讨论】:
标签: c shell unix io-redirection
你可以通过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)。
【讨论】:
我希望找到主要使用的dup2()。
popen() 和 freopen() 均未设计用于处理重定向,例如 3>&7。在某种程度上,可以使用dup(),但3>&7 示例显示了dup() 开始吱吱作响的地方;您必须确保文件描述符 4、5 和 6 已打开(而 7 未打开),然后它才能处理 dup2() 的操作。
【讨论】:
dup2()。所以你似乎是对的! +1