如果使用execl()运行/bin/ls-R,如何获取其返回值?

如果使用execl()运行/bin/ls-R,如何获取其返回值?,c,linux,parent-child,C,Linux,Parent Child,因此,在Linux C中,我有一个Uni的赋值。程序必须调用一个子进程,该子进程必须运行/bin/ls-R命令,然后在父进程中写出返回值,该值不能为0。到目前为止,我只能使用system()调用使它工作,但我不能使用它。wait(&value)行与system()函数一起工作,但与execl不一起工作。到目前为止,我提出的代码是: int main(){ int value=0; if(fork() == 0){ printf("Running command,

因此,在Linux C中,我有一个Uni的赋值。程序必须调用一个子进程,该子进程必须运行
/bin/ls-R
命令,然后在父进程中写出返回值,该值不能为0。到目前为止,我只能使用
system()
调用使它工作,但我不能使用它。
wait(&value)
行与
system()
函数一起工作,但与
execl
不一起工作。到目前为止,我提出的代码是:

int main(){
    int value=0;
    if(fork() == 0){
        printf("Running command, please wait..\n");
        sleep(2);
        char *path = "/bin/ls";
        char *arg1 = "-R";
        execl(path, arg1, NULL);
        exit(1);
    }

    wait(&value); 
    printf("\nProcessing return value, please wait..\n");
    sleep(2);
    printf("\nThe return value of the child: %d \n", value); 
}
如果使用execl()运行/bin/ls-R,如何获取其返回值

如果您
wait()
正确(请参阅我答案的底部),那么您将获得
/bin/ls-R
的返回值

那不可能是0

不确定这是什么意思,但退出状态为
0
表示进程已正确退出。与
0
不同的内容意味着发生了错误,因此您通常希望使用
0
退出,而不是其他内容

执行成功时,
exec*()
函数系列不会返回。想知道更多

如果您希望子级失败,则将无效路径传递到
execl
以使其失败,或者直接
返回1
。为了使
ls-R
返回与
0
不同的内容,您可能需要将第三个参数传递给
execl()
,指向您无权访问的路径,例如
/root


我也不完全确定您的代码出了什么问题,因为它可以在我的机器上正确编译和工作,但是,这里有一些经验法则,既可以找到问题,也可以从一开始就避免问题:

  • 务必阅读手册(在这种情况下):

    如果wstatus不为NULL,wait()和waitpid()将状态信息存储在它所指向的int中。这
    可以使用以下宏(将整数本身作为参数,而不是参数)检查整数
    指向它的指针,如wait()和waitpid()中所述:
    妻子退出(wstatus)
    如果子级正常终止,即通过调用exit(3)或_exit(2)或通过return-
    正在从main()中删除。
    WEXITSTATUS(wstatus)
    返回子级的退出状态。这由状态的最低有效8位组成
    子级在对exit(3)或_exit(2)的调用中指定的参数,或作为返回的参数
    main()中的语句。只有当WIFEXITED返回true时,才应使用此宏。
    
  • 始终检查可能失败的函数上的错误。提示:基本上99%的系统调用可能会失败,
    fork
    wait
    就是其中的一些

    pid_t child_pid = fork();
    if (child_pid == -1) {
        perror("fork() failed");
        return 1;
    }
    
    // ...
    
    pid_t res = wait(&child_status);
    if (res != child_pid) {
        perror("wait() failed");
        return 1;
    }
    
  • 始终编译启用警告:
    gcc-Wall-Wextra-pedantic

  • 大多数情况下,应用上述规则是您找出问题所在所需的全部。以下是应用程序后的工作版本:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int main(void) {
        pid_t child_pid, res;
        int child_status;
    
        child_pid = fork();
        if (child_pid == -1) {
            perror("fork() failed");
            return 1;
        }
    
        if(child_pid == 0) {
            sleep(123);
            execl("/bin/ls", "-R", NULL);
            perror("execl() failed");
            exit(1);
        }
    
        res = wait(&child_status);
        if (res != child_pid) {
            perror("wait() failed");
            return 1;
        }
    
        if (WIFEXITED(child_status))
            printf("Child exited with status %d.\n", WEXITSTATUS(child_status));
        else if (WIFSIGNALED(child_status))
            printf("Child killed by signal %d.\n", WTERMSIG(child_status));
        else {
            puts("This should never happen! Something's really wrong.");
            return 1;
        }
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    内部主(空){
    pid_t child_pid,res;
    国际儿童基金会地位;
    child_pid=fork();
    如果(子项pid==-1){
    perror(“fork()失败”);
    返回1;
    }
    如果(子项pid==0){
    睡眠(123);
    execl(“/bin/ls”,“-R”,空);
    perror(“execl()失败”);
    出口(1);
    }
    res=等待(和子_状态);
    如果(res!=子对象){
    perror(“wait()失败”);
    返回1;
    }
    如果(妻子退出(子女身份))
    printf(“子项已退出,状态为%d.\n”,WEXITSTATUS(子项状态));
    else if(WIFSIGNALED(child_状态))
    printf(“被信号%d杀死的子对象。\n”,WTERMSIG(子对象状态));
    否则{
    puts(“这不应该发生!真的出了问题。”);
    返回1;
    }
    返回0;
    }
    
    如果使用execl()运行/bin/ls-R,如何获取其返回值

    如果您
    wait()
    正确(请参阅我答案的底部),那么您将获得
    /bin/ls-R
    的返回值

    那不可能是0

    不确定这是什么意思,但退出状态为
    0
    表示进程已正确退出。与
    0
    不同的内容意味着发生了错误,因此您通常希望使用
    0
    退出,而不是其他内容

    执行成功时,
    exec*()
    函数系列不会返回。想知道更多

    如果您希望子级失败,则将无效路径传递到
    execl
    以使其失败,或者直接
    返回1
    。为了使
    ls-R
    返回与
    0
    不同的内容,您可能需要将第三个参数传递给
    execl()
    ,指向您无权访问的路径,例如
    /root


    我也不完全确定您的代码出了什么问题,因为它可以在我的机器上正确编译和工作,但是,这里有一些经验法则,既可以找到问题,也可以从一开始就避免问题:

  • 务必阅读手册(在这种情况下):

    如果wstatus不为NULL,wait()和waitpid()将状态信息存储在它所指向的int中。这
    可以使用以下宏(将整数本身作为参数,而不是参数)检查整数
    指向它的指针,如wait()和waitpid()中所述:
    妻子退出(wstatus)
    如果子级正常终止,即通过调用exit(3)或_exit(2)或通过return-
    正在从main()中删除。
    WEXITSTATUS(wstatus)
    返回子级的退出状态。这由状态的最低有效8位组成
    子级在对exit(3)或_exit(2)的调用中指定的参数,或作为返回的参数
    main()中的语句。只有当WIFEXITED返回true时,才应使用此宏。
    
  • 始终检查可能失败的函数上的错误。提示:基本上99%的系统调用都可能失败,