使用 execvp 传递参数
Passing an argument using 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
./parent
这会打印出 "This is the child (null)" 6 次,这是我所期望的。但是我希望能够像我运行 child一样传递一个参数,在本例中是进程号。
所以我把我的 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);
}
我以为我的程序会打印 "This is the child 1"、"This is the child 2" 等...
然而,实际发生的是该程序似乎 运行 parent.c 无数次(我在 parent.c 的开头放置了一条打印语句,输出打印了该语句,如20 次)而不是 child.c
谁能解释为什么会这样?还有另一种方法可以将参数传递给 child.c?
谢谢
Can anyone explain why this is happening? Is there another way I can pass a parameter to child.c?
您应该将 char* 数组传递给 execvp,而不是 char*。如评论中所述,数组的最后一个元素应该是空指针。以下应该有效:
char* args[] = {"1[=10=]", NULL};
execvp(command, args);
我猜 execvp 失败了,因为它不能将 args 取消引用为 char**,因此分叉进程作为父进程继续循环。您应该检查 execvp 的 return 值以查看函数调用是否有效。
另外,command 和 args 应该以 null 结尾。我建议使用函数 itoa
将 int 转换为 c 字符串。
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.
您的程序目前存在几个问题。首先,正如其他人所描述的,execvp 的第二个参数是一个 char ** 类型......它最终作为 exec 程序中的 argv。
二、
如果(我== 1){
字符*参数=“1”;
}
...
代码设置一个变量 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;
}
我的 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
./parent
这会打印出 "This is the child (null)" 6 次,这是我所期望的。但是我希望能够像我运行 child一样传递一个参数,在本例中是进程号。
所以我把我的 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);
}
我以为我的程序会打印 "This is the child 1"、"This is the child 2" 等...
然而,实际发生的是该程序似乎 运行 parent.c 无数次(我在 parent.c 的开头放置了一条打印语句,输出打印了该语句,如20 次)而不是 child.c
谁能解释为什么会这样?还有另一种方法可以将参数传递给 child.c?
谢谢
Can anyone explain why this is happening? Is there another way I can pass a parameter to child.c?
您应该将 char* 数组传递给 execvp,而不是 char*。如评论中所述,数组的最后一个元素应该是空指针。以下应该有效:
char* args[] = {"1[=10=]", NULL};
execvp(command, args);
我猜 execvp 失败了,因为它不能将 args 取消引用为 char**,因此分叉进程作为父进程继续循环。您应该检查 execvp 的 return 值以查看函数调用是否有效。
另外,command 和 args 应该以 null 结尾。我建议使用函数 itoa
将 int 转换为 c 字符串。
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.
您的程序目前存在几个问题。首先,正如其他人所描述的,execvp 的第二个参数是一个 char ** 类型......它最终作为 exec 程序中的 argv。
二、 如果(我== 1){ 字符*参数=“1”; } ... 代码设置一个变量 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;
}