argv如何在这个execvp调用中工作?

时间:2017-10-26 06:00:28

标签: c

我正在研究Unix系统调用(execvp)并且对此代码感到困惑。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[]){
    if(argc < 2){
        perror("little arguments");
        return -1;
    }
    execvp(argv[1], &argv[1]);
    return 0;
}

我的问题是:为什么execvp的第二个参数&argv[1]?根据我对execvp的了解,第二个参数应该是一个命令数组(例如ls -l),我不认为&argv[1]是一个命令数组。它只是一个字符串的地址,对吧?但是此代码与任何命令完美匹配(例如./a.out ls./a.out ls -l,...)。

1 个答案:

答案 0 :(得分:0)

继续上述两条评论:

  

这只是一个字符串的地址,对吗?

右。 地址(例如指向的指针)字符串。 execvp需要char *const argv[]作为第二个参数。 (一个指向char 的const指针数组)。 &argv[1]只提供 const指针数组的起始地址为char

由于你有一个指向char的指针数组,一个可视化正在发生的事情的简单方法就是printf数组中每个指针(每个字符串)的内容。您可以通过索引进行迭代,或者声明指向第一个指针的指针,并通过简单地使用指针算法迭代每个指针。

一个简单的例子就是向代码中添加一个快速char **p = &argv[1];,然后迭代将传递给execvp(直到结束NULL)的指针,看看是什么正在通过。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[]){
    if(argc < 2){
        perror("little arguments");
        return -1;
    }
    int n = 1;              /* declare a counter variable */
    char **p = &argv[n];    /* declare a pointer to pointer to argv[1] */
    while (*p)              /* iterate over each pointer, and index */
        printf ("points to argv[%d]: '%s'\n", n++, *p++);
    execvp(argv[1], &argv[1]);
    return 0;
}

示例使用/输出

$ ./bin/execvp ls -l dat
points to argv[1]: 'ls'
points to argv[2]: '-l'
points to argv[3]: 'dat'
total 892
-rw-r--r-- 1 david david    31 May  6  2016 11nums.txt
...

仔细看看,如果您对评论或答案有疑问,请告诉我。