重定向子进程的输出
有多种方法可以重定向子进程的输出:
- 使用
freopen(3)
- 使用
dup(3)
- 使用
popen(3)
- 。 ..
如果需要的话,应该选择执行一个子进程并将其输出保存在给定文件中,非常类似于 ls > 。 files.txt 有效吗?
shell通常使用什么?
There are several ways of redirecting the output of a child process:
- using
freopen(3)
- using
dup(3)
- using
popen(3)
- ...
What should one pick if all is wanted is to execute a child process and have it output saved in a given file, pretty much like the ls > files.txt
works?
What is normally used by shells?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以通过
strace(1)
您的 shell 来发现您最喜欢的 shell 使用的内容。在一个终端中:
在另一个终端中:
再次在第一个终端中:
在第二个终端中,
^C
您的strace(1)
命令,然后编辑/tmp /shell
输出文件以查看它为执行重定向而进行的系统调用。freopen(3)
操作 C 标准 IOFILE*
指针。所有这些都将在execve(2)
调用的另一端被丢弃,因为它保存在用户内存中。您可以在execve(2)
调用之后使用此函数,但一般使用起来会很尴尬。popen(3)
打开单个单向pipe(7)
。这很有用,但极其有限——您可以获得标准输出描述符或标准输入描述符。对于像 ls | 这样的东西,这会失败。 grep foo | sort 输入和输出都必须重定向。所以这是一个糟糕的选择。dup2(2)
将管理文件描述符(一种内核实现的资源),因此它将在execve(2)
调用和您之间持续存在可以根据需要设置任意数量的文件描述符,这对于 ls > 来说很好。 /tmp/输出2> /tmp/error 或处理输入和输出:ls |排序|唯一性。
还有另一种机制:
pty(7)
处理。forkpty(3)
、openpty(3)
函数可以管理专门为处理另一个程序而创建的新伪终端设备。 Unix 环境中的高级编程,第二版 有一个非常好的pty
示例程序在其源代码中,但是如果您无法理解为什么这有用,请查看script(1)
程序 - 它创建一个新的伪终端并使用它来记录程序的所有输入和输出,并将记录存储到供以后播放或记录的文件。您还可以使用它在交互式程序中编写操作脚本,类似于expect(1)
。You can discover what your favorite shell uses by
strace(1)
ing your shell.In one terminal:
In another terminal:
In the first terminal again:
In the second terminal,
^C
yourstrace(1)
command and then edit the/tmp/shell
output file to see what system calls it made to do the redirection.freopen(3)
manipulates the C standard IOFILE*
pointers. All this will be thrown away on the other side of theexecve(2)
call, because it is maintained in user memory. You could use this after theexecve(2)
call, but that would be awkward to use generically.popen(3)
opens a single unidirectionalpipe(7)
. This is useful, but extremely limited -- you get either the standard output descriptor or the standard input descriptor. This would fail for something likels | grep foo | sort
where both input and output must be redirected. So this is a poor choice.dup2(2)
will manage file descriptors -- a kernel-implemented resource -- so it will persist acrossexecve(2)
calls and you can set up as many file descriptors as you need, which is nice forls > /tmp/output 2> /tmp/error
or handling both input and output:ls | sort | uniq
.There is another mechanism:
pty(7)
handling. Theforkpty(3)
,openpty(3)
, functions can manage a new pseudo-terminal device created specifically to handle another program. The Advanced Programming in the Unix Environment, 2nd edition book has a very nicepty
example program in its source code, though if you're having trouble understanding why this would be useful, take a look at thescript(1)
program -- it creates a new pseudo-terminal and uses it to record all input and output to and from programs and stores the transcript to a file for later playback or documentation. You can also use it to script actions in interactive programs, similar toexpect(1)
.我希望找到主要使用的
dup2()
。popen()
和freopen()
均未设计用于处理诸如3>&7
之类的重定向。在某种程度上,可以使用dup()
,但是3>&7
示例显示了dup()
开始吱吱作响的地方;您必须确保文件描述符 4、5 和 6 已打开(而 7 未打开),然后它才能顺利处理 dup2() 所做的事情。I would expect to find
dup2()
used mainly.Neither
popen()
norfreopen()
is designed to handle redirections such as3>&7
. Up to a point,dup()
could be used, but the3>&7
example shows wheredup()
starts to creak; you'd have to ensure that file descriptors 4, 5, and 6 are open (and 7 is not) before it would handle whatdup2()
would do without fuss.