我很困惑popen()如何在unix中重定向子进程的stdin,stdout和stderr.关于popen()的手册页在这方面不是很清楚.电话
FILE *p = popen("/usr/bin/foo", "w");
Run Code Online (Sandbox Code Playgroud)
分叉子进程并执行带参数"-c","/ usr/bin/foo"的shell,并重定向此shell的stdin(重定向foo的stdin),stdout到p.但是stderr会发生什么?它背后的一般原则是什么?
我注意到,如果我在foo中打开一个文件(使用fopen,socket,accept等),并且父进程没有stdout,它会被分配下一个可用的文件号,即1,依此类推.这会从fprintf(stderr,...)等调用中产生意外结果.
写作可以避免
FILE *p = popen("/usr/bin/foo 2>/dev/null", "w");
Run Code Online (Sandbox Code Playgroud)
在父计划中,但他们是更好的方法吗?
我正试图用来popen()捕捉一个电话的stderr,但当然它似乎并没有这样做.有任何想法吗?
我的代码看起来或多或少像这样:
popen("nedit", "r");
Run Code Online (Sandbox Code Playgroud)
但是我在屏幕上得到了关于非utf8的所有垃圾......
我需要实现处理多个管道命令的 shell。例如,我需要能够处理这个:ls | grep -i cs340 | sort | uniq | cut -c 5。我假设问题是我没有将上一个命令的输出传递给下一个命令的输入。当我执行代码时,它没有给我任何输出。我正在使用这个伪代码:
for cmd in cmds
if there is a next cmd
pipe(new_fds)
fork
if child
if there is a previous cmd
dup2(old_fds[0], 0)
close(old_fds[0])
close(old_fds[1])
if there is a next cmd
close(new_fds[0])
dup2(new_fds[1], 1)
close(new_fds[1])
exec cmd || die
else
if there is a previous cmd
close(old_fds[0])
close(old_fds[1])
if there is a next cmd
old_fds = new_fds
if there are multiple cmds
close(old_fds[0])
close(old_fds[1])
Run Code Online (Sandbox Code Playgroud)
这是处理多个管道的函数的源代码。 …
几天我就提出了一个问题.我的解决方案符合接受的答案中的建议.但是,我的一个朋友提出了以下解决方案:
请注意,代码已更新几次(查看编辑修订版)以反映下面答案中的建议.如果您打算给出新的答案,请考虑这个新代码,而不是那些有很多问题的旧代码.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[]){
int fd[2], i, aux, std0, std1;
do {
std0 = dup(0); // backup stdin
std1 = dup(1); // backup stdout
// let's pretend I'm reading commands here in a shell prompt
READ_COMMAND_FROM_PROMPT();
for(i=1; i<argc; i++) {
// do we have a previous command?
if(i > 1) {
dup2(aux, 0);
close(aux);
}
// do we have a next command?
if(i < argc-1) { …Run Code Online (Sandbox Code Playgroud)