使用execvp传递参数

时间:2015-03-18 00:50:22

标签: c gcc fork execvp

我在parent.c文件中有这个

int main()
{
int n = 6;
int pid;
int status;
char* command = "./child";
for (i=1; i<=n; i++){


    if((pid = fork()) == 0) {
        execvp(command, NULL);
    }
    wait(&status);
}

我的child.c文件看起来像这样

int main(int argc, char *argv[]){
    char *processnum = argv[0];
    printf("This is the child %s\n", processnum);
    return 0;
}

我基本上只是跑了

gcc -o parent parent.c

gcc -o child child.c

./父

打印输出&#34;这是孩子(null)&#34; 6次,这是我所期待的。但是我希望能够在运行子进程时传递参数,在这种情况下是进程号。

所以我改变了我的parent.c看起来像这样

for (i=1; i<=n; i++){
    if(i == 1){
        char* args = "1";
    }
    if(i == 2){
        char* args = "2";
    }
    if(i == 3){
        char* args = "3";
    }
    if(i == 4){
        char* args = "4";
    }
    if(i == 5){
        char* args = "5";
    }
    if(i == 6){
        char* args = "6";
    }

    if((pid = fork()) == 0) {
        execvp(command, args);
    }
    wait(&status);
}

我认为会发生的是我的程序会打印出#34;这是孩子1&#34;,&#34;这是孩子2&#34;等...

然而,实际发生的事情是该程序似乎多次运行parent.c(我在parent.c的开头放了一个print语句,输出打印了20次这样的语句)而不是child.c

任何人都可以解释为什么会这样吗?有没有其他方法可以将参数传递给child.c?

由于

3 个答案:

答案 0 :(得分:1)

here is the critical excerpt from the man page for execvp()

   The execv(), execvp(), and execvpe()  functions  provide  an  array  of
   pointers  to  null-terminated  strings that represent the argument list
   available to the new  program.   The  first  argument,  by  convention,
   should  point  to the filename associated with the file being executed.
   The array of pointers must be terminated by a NULL pointer.

答案 1 :(得分:0)

您的程序有几个问题。首先,正如其他人所描述的那样,execvp的第二个参数是char **类型......它最终成为exec'ed程序中的argv。

第二,     if(i == 1){         char * args =“1”;     }     ... 代码设置一个变量args,其范围在下一行结束。您必须在要使用它的范围内声明args。

第三,将数字转换为这样的字符串是非常有限和繁琐的!你可以使用标准的C函数sprintf(甚至更好的snprintf)做得更好。

这是更新后的parent.c:

#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
        int n = 6;
        int pid;
        int status;
        char* command = "./child";
        char *child_args[2];
        char number_buff[32];   // more than big enough to hold any number!

        child_args[1] = NULL;
        for (int i=1; i<=n; i++){
                sprintf(number_buff, "%d", i);
                child_args[0] = number_buff;
                if((pid = fork()) == 0) {
                        execvp(command, child_args);
                }
                wait(&status);
        }
        return 0;
}

答案 2 :(得分:-1)

  

任何人都可以解释为什么会这样吗?有没有其他方法可以将参数传递给child.c?

您应该将char *数组传递给execvp,而不是char *。正如注释中所提到的,数组的最后一个元素应该是一个空指针。以下应该有效:

char* args[] = {"1\0", NULL};
execvp(command, args);

我猜测execvp失败了,因为它不能将args取消引用为char **,因此分叉进程继续作为父进程循环。你应该检查execvp的返回值,看看函数调用是否有效。

此外,命令和args应该以null结尾。我建议使用函数itoa将int转换为c字符串。