我非常接近弄清楚我一直在为用 C 编写的 linux shell 编写的程序。我一直想让它工作一段时间,我决定把它捡起来过去几周一直在修补它。
对于以下代码,请记住称为arrayOfCommands 的数组是动态填充的。我的代码用当前正在运行的命令填充 arrayOfCommands。为了我的示例,我们将运行命令 ls -l | wc 和 arrayOfCommands 填充了以下内容,具体取决于循环的时间:
//Pass #1
arrayOfCommands[]= ("ls", "-l", NULL)
//Pass #2
arrayOfCommands[]= ("wc", NULL)
这是我目前所拥有的:
//PIPING
int do_command(char **args, int pipes) {
// pipes is the number of pipes in the command
// (In our example, one)
// The number of commands is one more than the
// number of pipes (In our example, two)
const int commands = pipes + 1; //Ex: 2
int i = 0;
// Set up the pipes
int pipefds[2*pipes];
for(i = 0; i < pipes; i++){
if(pipe(pipefds + i*2) < 0) {
perror("Couldn't Pipe");
exit(EXIT_FAILURE);
}
}
// Variables
int pid;
int status;
char *str_ptr;
int j = 0;
for (i = 0; i < commands; ++i) {
// A magic function that updates arrayOfCommands with
// the current command goes here. It doesn't make
// sense in the context of the code, so just believe me! :)
// Ex: The contents will be "ls -l" or "wc" depending on
// which time through the loop we are
pid = fork();
if(pid == 0) {
//if not last command
if(i < commands){
if(dup2(pipefds[j + 1], 1) < 0){
perror("dup2");
exit(EXIT_FAILURE);
}
}
//if not first command&& j!= 2*pipes
if(j != 0 ){
if(dup2(pipefds[j-2], 0) < 0){
perror("dup2");
exit(EXIT_FAILURE);
}
}
for(i = 0; i < 2*pipes; i++){
close(pipefds[i]);
}
// Should any of the below inputs be *arrayOfCommands or
// **arrayOfCommands or &arrayOfCommands?
// I'm REALLY bad with pointers
if( execvp(arrayOfCommands, arrayOfCommands) < 0 ){
perror(arrayOfCommands);
exit(EXIT_FAILURE);
}
}
else if(pid < 0){
perror("error");
exit(EXIT_FAILURE);
}
j+=2;
}
for(i = 0; i < 2 * pipes; i++){
close(pipefds[i]);
}
for(i = 0; i < pipes + 1; i++){
}
wait(&status);
}
当我运行它时,出现了一些错误:
- dup2:错误的文件描述符
- ls: |: 没有那个文件或目录
- ls: wc: 没有那个文件或目录
谁能帮我弄清楚以下两件事:
- 为什么会出现这些错误?
- 在 execvp 函数中,我在寻找什么样的 if 指针? arrayOfCommands 被初始化为一个 char *arrayOfArgs[]
最佳答案
第一件事:
//if not last command
if(i < commands)
应该是
if(i < commands -1)
因为 i
从 0
到 commands -1
那应该解决 dup2: Bad file descriptor
ls: |: 没有那个文件或目录
ls: wc: 没有那个文件或目录
由格式错误的 arrayOfCommands
引起。它必须被初始化
char * arrayOfCommands[] = {"ls", "-l", NULL};
和
char * arrayOfCommands[] = {"wc", NULL};
分别通过execvp(arrayOfCommands[0], arrayOfCommands)
调用
本质上,arrayOfCommands
的格式必须与 int main(int argc, char** argv) 的参数 vector (通常是
。argv
)相同
关于c - 在循环中执行多个管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12666152/