我目前正在实施&&使用C在shell中运行。例如,如果我们输入cmd1&& cmd2,然后cmd2仅在cmd1成功退出时执行。我在考虑:
int main() {
int i;
char **args;
while(1) {
printf("yongfeng's shell:~$ ");
args = get_line();
if (strcmp(args[0], "exit") == 0) exit(0); /* if it's built-in command exit, exit the shell */
if('&&') parse_out_two_commands: cmd1, cmd2;
if (execute(cmd1) != -1) /* if cmd1 successfully executed */
execute(cmd2); /* then execute the second cmd */
}
}
int execute(char **args){
int pid;
int status; /* location to store the termination status of the terminated process */
char **cmd; /* pure command without special charactors */
if(pid=fork() < 0){ //fork a child process, if pid<0, fork fails
perror("Error: forking failed");
return -1;
}
/* child */
else if(pid==0){ /* child process, in which command is going to be executed */
cmd = parse_out(args);
/* codes handleing I/O redirection */
if(execvp(*cmd, cmd) < 0){ /* execute command */
perror("execution error");
return -1;
}
return 0;
}
/* parent */
else{ /* parent process is going to wait for child or not, depends on whether there's '&' at the end of the command */
if(strcmp(args[sizeof(args)],'&') == 0){
/* handle signals */
}
else if (pid = waitpid(pid, &status, 0) == -1) perror("wait error");
}
}
所以我正在使用另一个函数int execute(char ** args)来完成实际的工作。它的返回类型是int,因为我想知道命令是否成功退出。但是我不确定父进程是否可以从子进程获得返回值,因为它们是两个不同的进程。
或者我应该通过分支另一个进程来决定是否在子进程中执行第二个命令?非常感谢。
答案 0 :(得分:3)
变化:
if(pid=fork() < 0){ //fork a child process, if pid<0, fork fails
为:
if((pid=fork()) < 0){ //fork a child process, if pid<0, fork fails
您将pid
设置为fork() < 0
的结果,而不是将其设置为孩子的PID。因此,除非fork()
出现错误,否则会在父级和子级中将pid
设置为0
,因此他们都认为自己是孩子。
关于execute()
函数的返回值:它将在父级和子级中返回。在每个进程中,它将返回return
中if
的相应分支中execute()
语句中指定的内容。注意它execve()
成功,孩子永远不会返回,因为它不再运行这个程序,它正在运行被执行的程序。
如果孩子想要向父母发送成功或失败信息,则使用其退出状态,通过调用exit(0)
表示成功,exit(some-nonzero-value)
表示失败。父级可以使用waitpid
获取退出状态,然后从execute()
返回成功或失败指示。