简体   繁体   English

重定向子进程的输出

[英]Redirecting the output of a child process

There are several ways of redirecting the output of a child process: 有几种方法可以重定向子进程的输出:

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

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? 如果只需要一个子程序,那就是执行一个子进程并将其输出保存在给定的文件中,就像ls > files.txt工作原理一样?

What is normally used by shells? 贝壳通常使用什么?

You can discover what your favorite shell uses by strace(1) ing your shell. 您可以通过strace(1) shell来发现自己喜欢的shell使用的东西。

In one terminal: 在一个终端中:

echo $$

In another terminal: 在另一个终端:

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

In the first terminal again: 再次在第一个终端中:

ls > files.txt

In the second terminal, ^C your strace(1) command and then edit the /tmp/shell output file to see what system calls it made to do the redirection. 在第二个终端中, ^C您的strace(1)命令,然后编辑/tmp/shell输出文件以查看进行重定向的系统调用。


freopen(3) manipulates the C standard IO FILE* pointers. freopen(3)操作C标准IO FILE*指针。 All this will be thrown away on the other side of the execve(2) call, because it is maintained in user memory . 所有这些都将在execve(2)调用的另一端丢弃,因为它保存在用户内存中 You could use this after the execve(2) call, but that would be awkward to use generically. 您可以在execve(2)调用之后使用它,但是一般使用会很尴尬。

popen(3) opens a single unidirectional pipe(7) . popen(3)打开一个单向pipe(7) This is useful, but extremely limited -- you get either the standard output descriptor or the standard input descriptor. 这很有用,但非常有限-您可以使用标准输出描述符标准输入描述符。 This would fail for something like ls | grep foo | sort 对于ls | grep foo | sort这样的操作将失败。 ls | grep foo | sort ls | grep foo | sort where both input and output must be redirected. ls | grep foo | sort必须同时重定向输入和输出的位置。 So this is a poor choice. 因此,这是一个糟糕的选择。

dup2(2) will manage file descriptors -- a kernel-implemented resource -- so it will persist across execve(2) calls and you can set up as many file descriptors as you need, which is nice for ls > /tmp/output 2> /tmp/error or handling both input and output: ls | sort | uniq dup2(2)将管理文件描述符(一种内核实现的资源),因此它将在execve(2)调用之间持久存在, 并且您可以根据需要设置任意数量的文件描述符,这对于ls > /tmp/output 2> /tmp/error或同时处理输入输出: ls | sort | uniq ls | sort | uniq ls | sort | uniq . ls | sort | uniq

There is another mechanism: pty(7) handling. 还有另一种机制: pty(7)处理。 The forkpty(3) , openpty(3) , functions can manage a new pseudo-terminal device created specifically to handle another program. forkpty(3)openpty(3)函数可以管理专门为处理另一个程序而创建的新伪终端设备。 The Advanced Programming in the Unix Environment, 2nd edition book has a very nice pty example program in its source code, though if you're having trouble understanding why this would be useful, take a look at the script(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. Unix环境下Advanced Programming,第2版书的源代码中有一个非常漂亮的pty示例程序,尽管如果您无法理解为什么这样做有用,请看一下script(1)程序-创建一个新的伪终端,并使用它来记录与程序之间的所有输入和输出,并将脚本存储到文件中以供以后播放或记录。 You can also use it to script actions in interactive programs, similar to expect(1) . 您还可以使用它来编写交互式程序中的动作脚本,类似于expect(1)

I would expect to find dup2() used mainly. 我希望找到主要使用的dup2()

Neither popen() nor freopen() is designed to handle redirections such as 3>&7 . popen()freopen()都不用于处理重定向,例如3>&7 Up to a point, dup() could be used, but the 3>&7 example shows where dup() starts to creak; 到目前为止,可以使用dup() ,但是3>&7示例显示dup()开始发出吱吱声; you'd have to ensure that file descriptors 4, 5, and 6 are open (and 7 is not) before it would handle what dup2() would do without fuss. 您必须确保文件描述符4、5和6已打开(而7没有打开),然后它才能处理dup2()不会引起大惊小怪的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM