Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Execvp(argv[1],argv),不返回此类文件或目录_C_Linux_Exec_Execvp - Fatal编程技术网

Execvp(argv[1],argv),不返回此类文件或目录

Execvp(argv[1],argv),不返回此类文件或目录,c,linux,exec,execvp,C,Linux,Exec,Execvp,我正在编写一个C程序,它接受参数,char*argv[]来决定运行哪个exec()。我已经让execlp(argv[1],argv[1],NULL)正常工作。由于某种原因,execvp(argv[1],argv)无法找到要运行的“ls”命令。我真正需要的是,如果我有多个参数,不包括调用/filexec,我可以运行exec(),它将接受char*argv[],而不包括文件路径。我的理解是,execvp()有能力做到这一点 我在ssh-linux服务器上运行这个 int main(int argc,

我正在编写一个C程序,它接受参数,
char*argv[]
来决定运行哪个
exec()
。我已经让
execlp(argv[1],argv[1],NULL)
正常工作。由于某种原因,
execvp(argv[1],argv)
无法找到要运行的“ls”命令。我真正需要的是,如果我有多个参数,不包括调用
/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;
}

等等。

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

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

显然,对于调用
execlp
,您已经明白了这一点,因为您指定了
argv[1]
两次,一次作为
exec
的程序名,一次作为
argv
数组中传递给该程序的第一个(也是唯一的)元素。您只需要对调用
execvp
执行相同的操作;您需要
execvp(argv[1],argv+1)
,而不是
execvp(argv[1],argv+1)

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

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

顺便说一下:

argv[argc++] = NULL;

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

我可以问一下argv+1为什么工作吗?这只是从argv[1]开始移动索引吗?跳过./a.out?@cameronPrestera:这将是一个很好的时机,可以返回到您的C编程教科书并查找指针算法。理解指针算法是非常非常重要的。根据我的理解,任何时候你有一个指针数组,做一个++或+1,它就会移动到数组中的下一个指针。我明白这一点,我想我的问题是“execvp是否将./a.out作为第一个参数?”,我可以看出这会导致错误。@cameron:如果您将
argv
作为
execvp
的参数,它就会认为该参数是这样的。
argv
中的第一件事是
argv[0]
,这正是
execvp
将传递给它运行的程序的内容。
argv[argc++] = NULL;