首页 > 解决方案 > Execvp(argv[1], argv),不返回这样的文件或目录

问题描述

我正在编写一个接受参数的 C 程序,char *argv[]以决定exec()运行哪个。我必须好好execlp(argv[1], argv[1], NULL)工作。由于某种原因execvp(argv[1], argv)找不到要运行的“ls”命令。我真正需要的是,如果我有多个参数,不包括 call ./filexec,我可以运行一个exec()将不包含char* argv[]文件路径的参数。我理解execvp()有能力做到这一点。

我在 ssh linux 服务器上运行它。

int main(int argc, char *argv[])
{
pid_t pid;

        /* fork a child process */
        pid = fork();

        if (pid < 0) {/* error occured */
                fprintf(stderr, "Fork Failed");
                return 1;
        }
        else if (pid == 0) {/* child process */
                //pass the right thing to the right exec?

                if (argc == 1)
                {
                        printf("CHILD started. No arguments provided. Terminating child.\n");
                }

                if (argc == 2)
                {
                        printf("CHILD started. One argument provided.      Calling execlp().\n");
                        execlp(argv[1],argv[1],NULL);
                }

                if (argc  >= 3)
                {
                        printf("CHILD started. More than one argument provided. Calling execvp().\n");
                        argv[argc++] = NULL;
                        execvp(argv[1],argv);
                }



        }
        else {/* parent process */
                /* parent will wait for the child to complete */
                printf("PARENT started, now waiting for processID#%u\n", getpid());
                wait(NULL);
                printf("PARENT resumed. Child exit code of 0. Now terminating parent.\n");
        }

        return 0;
}

我希望给予./a.out ls -l打电话execvp() 给:

total XXX
info ---------filename
info ---------filename

等等

标签: clinuxexecexecvp

解决方案


请记住,这argv[0]是“程序的名称”,因此当您的程序被调用时,它将类似于./a.out. 然后argv[1]是程序的第一个参数,它是您想要的程序的名称,exec其余的argv是传递给该程序的其余参数。

因此,argv您要传递给您要执行的程序的数组从argv[1]. 或者,更准确地说,argv您要提供的程序的指针execargv + 1.

显然,您已经知道了对 的调用execlp,因为您指定argv[1]了两次,一次作为程序名称,一次作为数组中要传递给该程序exec的第一个(也是唯一一个)元素。argv你只需要对调用做同样的事情execvp;而不是execvp(argv[1], argv),你需要execvp(argv[1], argv + 1).

您收到的错误消息来自ls实用程序本身。您已经调用lswith execvp,并将整个argv数组传递给它。换句话说,您已经告诉它它的名称是./a.out(这可能有点令人困惑,因为大多数实用程序都使用它们提供的程序名称来创建错误消息),并且您已经将它ls -l作为命令行参数提供。这实际上与命令行相同:

ls ls -l

如果您尝试一下,很可能会告诉您该文件ls不存在。ls(除非您碰巧在当前目录中有一个名为的文件。)

顺便一提:

argv[argc++] = NULL;

完全没有必要。argv[argc]已经保证为 NULL,并且您不需要该变量argc(如果您有一个,您可能需要它少一,而不是多一)。


推荐阅读