我使用pipes()forks()exec()dup()来模拟shell。我已经看到了stackoverflow上的一些帖子,以指导我们一路走来。但我的编程似乎与其他人在这里遇到过类似的问题。
我使用的LinkedList结构包含:char * cmd和char ** args(例如cmd ='ls'args =' - l -d')
以下是一些输出结果: ls -l ls -l -a(我想要多少个args) ls -l |排序
ls -l | wc -w (runs but spits out wrong value)
ls | wc -w (runs, but spits out the wrong value)
ls (alone - no args, spits out A NULL argv[0] was passed through an exec system call.)
ls -l | sort | wc -w (causes system to hang)
现在它至少假装它正在采取多个args但结果无效或系统挂起。
void runCommand(Node* head)
{
int old_fd[2], new_fd[2];
int isValid, cpid, pid;
//Loop through all commands
for(int cmd = 0; cmd < cmdCount; cmd++)
{
//if(curr cmd has next cmd)
if(cmd+1 < cmdCount)
{
//Create pipe new_fd
if( pipe(new_fd) == -1) //pipe error
{
perror("Pipe Error.");
exit(-1);
}
}
//Parent
if( (pid=fork()) != 0 ) //parent
{
//Wait for child process
//wait(0); //moved below
//Curr cmd has next command
if(cmd+1 < cmdCount)
{
old_fd[0] = new_fd[0];
old_fd[1] = new_fd[1];
}
//Curr cmd has previous command
if(cmd-1 > -1)
{
close(old_fd[0]);
close(old_fd[1]);
}
}
//Child process
else //if fork() == 0
{
//Curr cmd has previous command
if(cmd-1 > -1)
{
dup2(old_fd[0], 0); // setting up old_pipe to input into the child
close(old_fd[0]);
close(old_fd[1]);
}
//Curr cmd has next command
if(cmd+1 < cmdCount)
{
close(new_fd[0]); // setting up new_pipe to get output from child
dup2(new_fd[1], 1);
close(new_fd[1]);
}
printf("Running command '%s': \n",getCmd(cmd,head));
printf("Arguments: "); printArgs(cmd,head);
//Below works for 1 cmd 1+ args, but not 1 cmd 0 arg or mult pipes
isValid = execvp(getCmd(cmd,head), getArgs(cmd,head));
if(isValid == -1)
printf("%s: Command not found.\n", getCmd(cmd,head));
}
wait();
}
}
注意这个帖子:Another_Stack_Overflow_Example我在那里使用了这个例子,并用他们的“Working”样本替换了我的函数。他们的工作样本似乎适用于大多数事情,除了一个没有像“ls”之类的参数的命令,它根本就什么都不做。并要求输入
这是请求的getCmd()和getArgs()函数,只调用“getNode()”返回一个Node *结构(包含char *和一个char **和两个整数),getCmd提取char * cmd和getArgs提取char ** args。
char* getCmd(int index, Node* head)
{
Node* curr = getNode(index,head);
return curr->cmd;
}
char** getArgs(int index, Node* head)
{
Node* curr = getNode(index,head);
return curr->args;
}
答案 0 :(得分:0)
两件事:
1。 您应该将NULL终止的数组传递给 execvp():
execvp("ls", NULL); // invalid!!!
这应该是:
const char *args[1] = { NULL };
execvp("ls", args);
2。 “管道操作员”|是一个shell扩展,因此您无法在 exec ... 函数中使用它。您只能在那里指定一个可执行文件。