wc: '标准输入':错误的文件描述符
我正在使用 Exec 系列函数模拟 C 语言中的 bash 命令。
这只是更大项目的部分代码。为了简单起见,现在大多数内容都是硬编码的,但将来我需要使用管道或重定向运算符执行任何 bash 命令,这就是代码循环的原因。我知道我可以使用单个文件描述符(不带二维数组)来实现当前示例的结果,但我需要概括多个 |, > 的代码命令。我无法删除循环。
即使正确关闭所有描述符后,我也会收到“错误描述符”错误。无法找到原因。
int main()
{
int numOfCmds = 2;
int numOfPipes = numOfCmds -1;
int pipes[numOfPipes][2];
for(int i=0;i<numOfPipes;i++)
if(pipe(pipes[i])<0) return 1;
for(int i=0;i<numOfCmds;i++)
{
int child = fork();
if(child == 0)
{
if(i==0)
{
for(int i=0;i<numOfPipes;i++)
{
close(pipes[i][0]);
}
printf("hey\n");
dup2(pipes[i][1], STDOUT_FILENO);
close(pipes[i][1]);
char *cmd1_args[3] = {"ls", "-l", NULL};
execvp(cmd1_args[0], cmd1_args);
}
if(i==1)
{
for(int i=0;i<numOfPipes;i++)
{
close(pipes[i][1]);
}
printf("bye\n");
dup2(pipes[i][0], STDIN_FILENO);
close(pipes[i][0]);
char *cmd2_args[3] = {"wc", "-l", NULL};
execvp(cmd2_args[0], cmd2_args);
}
return 0;
}
}
for(int i=0;i<numOfCmds;i++)
{
for(int j=0;i<2;j++)
close(pipes[i][j]);
}
for(int i=0;i<numOfCmds;i++) wait(NULL);
return 0;
错误:
嘿再见 wc: '标准输入': 错误文件描述符 0 wc: -: 错误文件 描述符分段错误(核心转储)
I'm emulating bash commands in C language using Exec family of functions.
This is just a partial code of bigger project. Most of the things are hard-coded for now for simplicity, but in future I need to execute any bash command with Pipe or Redirection operator so that's the reason the code is in loop. I know I can use single file descriptor(with out 2d array) to achieve the result for current example but I need to generalise the code for multiple |, > commands. I can't remove the loop.
I'm getting Bad descriptor error even after closing all the descriptors correctly. Unable to find the reason.
int main()
{
int numOfCmds = 2;
int numOfPipes = numOfCmds -1;
int pipes[numOfPipes][2];
for(int i=0;i<numOfPipes;i++)
if(pipe(pipes[i])<0) return 1;
for(int i=0;i<numOfCmds;i++)
{
int child = fork();
if(child == 0)
{
if(i==0)
{
for(int i=0;i<numOfPipes;i++)
{
close(pipes[i][0]);
}
printf("hey\n");
dup2(pipes[i][1], STDOUT_FILENO);
close(pipes[i][1]);
char *cmd1_args[3] = {"ls", "-l", NULL};
execvp(cmd1_args[0], cmd1_args);
}
if(i==1)
{
for(int i=0;i<numOfPipes;i++)
{
close(pipes[i][1]);
}
printf("bye\n");
dup2(pipes[i][0], STDIN_FILENO);
close(pipes[i][0]);
char *cmd2_args[3] = {"wc", "-l", NULL};
execvp(cmd2_args[0], cmd2_args);
}
return 0;
}
}
for(int i=0;i<numOfCmds;i++)
{
for(int j=0;i<2;j++)
close(pipes[i][j]);
}
for(int i=0;i<numOfCmds;i++) wait(NULL);
return 0;
Error:
hey bye wc: 'standard input': Bad file descriptor 0 wc: -: Bad file
descriptor Segmentation fault (core dumped)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题是您正在重复使用
i
的(嵌套)定义。使用-wshadow
对GCC的选项避免这样做。i
的值有时超出了一对文件描述符数组的末尾,这会导致混乱(未定义的行为)。您有:
您的(外)循环控制变量为
i
;然后,您拥有一个由不同的i
控制的内部循环,该循环关闭了一些管道。我使用的GCC报告说,您正在访问管道[i] [0]
在dup2()
wc
的范围中。您需要重新使用
i
的使用(使用一些不同的名称 -j
和k
(对于'Kids'?)是可用的)。并重新审查您要仔细关闭的文件描述符。您的父母循环关闭文件描述符是:
您需要使用
numofpipes
而不是numofcmds
,并且您需要内部循环来测试 j ,而不是i
。这是一些有效的仪器代码。但是这些修复程序不是很通用:
一个示例运行(程序
sh83
,根据sh83.c
)产生:如果您使用多个进程,我会发现它如输出所示,可以将大多数消息的前缀前缀前缀。
Your problem is that you are reusing (nested) definitions of
i
. Use the-Wshadow
option to GCC to avoid doing that. And the value ofi
is sometimes beyond the end of the array of pairs of file descriptors, which leads to chaos (undefined behaviour).You have:
Your (outer) loop control variable is
i
; you then have an inner loop controlled by a differenti
that closes some pipes. And the GCC I use reports that you are accessingpipes[i][0]
out of bounds in thedup2()
call forwc
.You need to rework your use of
i
(use some different names —j
andk
(for 'kids'?) are usable). And re-review which file pipe descriptors you are closing carefully.Your parental loop closing file descriptors is:
You need to use the
numOfPipes
instead ofnumOfCmds
, and you need your inner loop to testj
, noti
.Here's some heavily instrumented code that works. But the fixes are not very general:
One sample run (of program
sh83
, compiled fromsh83.c
) yielded:If you're working with multiple processes, I find it is a great help to prefix most messages with a PID — as shown in the output.