【发布时间】:2019-07-06 06:48:12
【问题描述】:
我目前正在用 C 编写一个自定义 shell 脚本。为了执行命令,我使用了 execvp() 函数。例如:
if((execvp(args[0], args)) == -1) //args is a char **array containing the commands arguments
{
printf("ERROR: Wrong command\n");
exit(EXIT_FAILURE);
}
问题是,当两个命令用“&&”分隔时,如果第一个没有执行(因此,execvp 将返回-1),整个过程必须中断,然后才能进入下一个。它工作得很好,例如我写“一些随机错误的命令> && ls”。
虽然,如果我写类似“ ls 一些随机的错误路径> && ls ”,execvp() 将正常执行,并打印消息:
ls: cannot access '...': 没有这样的文件或目录
然后它会转到下一个命令。显然,在这种情况下 execvp() 不会返回 -1。
在这种情况下 execvp() 是否返回任何其他值?如果不存在,如何在执行命令前检查路径是否存在?
编辑 我只是检查状态的值(在父母等待孩子终止时由 wait(&status) 生成)。如果不为零,则表示该命令未执行。
【问题讨论】:
-
args数组失败时到底有什么?args[0]后跟NULL中的shell 脚本名称?类似{ "sh", "-c", "your shell commands", NULL }? -
注意
execvp(如果返回)的返回值是-1,而不是EXIT_FAILURE。如果返回,您可以查看errno。 -
对于
foo && bar这样的命令,需要在子进程中fork并执行foo,然后等待其退出状态再决定是否需要fork-and-execbar. -
如果这是一个自定义的shell程序,大概你是从子进程调用
execvp,而不是从主shell进程调用?您可以在主 shell 进程中添加代码以等待子进程退出,然后检查子进程的退出状态以决定如何继续。如果execvp函数在子进程中失败,那么子进程应该退出并报错,以便主shell进程可以检测到失败。 -
如果
ls报错你的execvp已经成功地用ls程序替换了你当前进程中的程序,所以execvp不会返回。您的进程将以退出代码ls终止。可以在父进程调用waitpid查看退出码。