我正在尝试将 stdin 更改为管道导出并将 stdout 更改为另一个文件并使用 grep。我收到以下错误:
grep: (standard input): Bad file descriptor
我的代码是:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
int main()
{
pid_t childpid;
int fds[2];
int stat;
int fd = open("temp", O_WRONLY | O_APPEND);
int old_in = dup(STDIN_FILENO);
int old_out = dup(STDOUT_FILENO);
if ((childpid = fork()) != 0)
{
wait(&stat);
close(fds[1]);
dup2(fds[0], STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
system("grep hello");
dup2(old_in, STDIN_FILENO);
dup2(old_out, STDOUT_FILENO);
close(fds[0]);
close(fd);
}
else if (childpid == 0)
{
close(fds[0]);
write(fds[1], "hello how are you", 100);
close(fds[1]);
return 0;
}
else
{
fprintf(stderr, "ERROR:\n");
exit(1);
}
return 0;
}
所以基本上我是将字符串写入管道的写入导出,并使用管道的另一个导出(读取)作为 grep 的标准输入,并将标准输出输出到另一个文件。我已经从 childpid 中删除了返回值,并尝试使用另一个文件作为标准输入,但仍然出现相同的错误。
最佳答案
有多个问题!其中:
您没有调用
pipe(fds);
,所以您没有管道。幼稚代码 (
write(fds[1], "hello how are you", 100);
)- 您应该在行尾包含一个换行符。
- 您应该只写与字符串中一样多的字符,并且显示的字符串中没有 100 个字符。
父代码(
if ((childpid = fork()) != 0)
之后的代码块)- 您不需要在
system
之后恢复文件描述符,因为您即将退出。 - 您可以使用
exec*()
函数之一代替system()
。 - 一般来说,你不应该等待 child 退出;可能有太多数据被插入管道,以至于 child 无法在 parent 读取任何内容之前完成。在这种情况下,应该没问题,但要小心。
- 您不应该在打开额外文件描述符(
old_in
和old_out
)的情况下真正执行grep
,但是当您不这样做时它们就会消失system()
调用后不要恢复。 - 您应该在复制后关闭
fds[0]
(在运行grep
之前)。
- 您不需要在
工作代码
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
int main(void)
{
pid_t childpid;
int fds[2];
int fd = open("temp", O_WRONLY | O_APPEND);
if (pipe(fds) != 0)
return 1;
if ((childpid = fork()) != 0)
{
close(fds[1]);
dup2(fds[0], STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
close(fds[0]);
close(fd);
execlp("grep", "grep", "hello", (char *)0);
fprintf(stderr, "Failed to execute grep\n");
return 1;
}
else if (childpid == 0)
{
const char data[] = "hello how are you\nvery well thanks\n";
close(fds[0]);
write(fds[1], data, sizeof(data)-1);
close(fds[1]);
return 0;
}
else
{
fprintf(stderr, "ERROR:\n");
return 1;
}
}
关于c - grep : (standard input): Bad file descriptor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22139665/