重定向子进程的输出

发布于 2024-12-21 23:05:08 字数 246 浏览 0 评论 0原文

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

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

如果需要的话,应该选择执行一个子进程并将其输出保存在给定文件中,非常类似于 ls > 。 files.txt 有效吗?

shell通常使用什么?

There are several ways of redirecting the output of a child process:

  1. using freopen(3)
  2. using dup(3)
  3. using 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?

What is normally used by shells?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

慕烟庭风 2024-12-28 23:05:08

您可以通过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/输出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:

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.


freopen(3) manipulates the C standard IO FILE* pointers. All this will be thrown away on the other side of the execve(2) call, because it is maintained in user memory. You could use this after the execve(2) call, but that would be awkward to use generically.

popen(3) opens a single unidirectional 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 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 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.

There is another mechanism: pty(7) handling. The forkpty(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 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. You can also use it to script actions in interactive programs, similar to expect(1).

笑咖 2024-12-28 23:05:08

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

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

I would expect to find dup2() used mainly.

Neither popen() nor freopen() is designed to handle redirections such as 3>&7. Up to a point, dup() could be used, but the 3>&7 example shows where dup() 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 what dup2() would do without fuss.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文