使用不带参数列表的 execv
Using execv without parameters list
我想从我的主程序中使用 fork 来创建我编写的其他程序的进程实例。
这是我正在尝试做的事情的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
int main(int argc, char *argv[]){
char *ar[] = {"./myfile",NULL};
switch (fork()) {
case -1:
printf("Problem.\n");
break;
case 0:
printf("Everything ok...\n");
execv("./myfile",ar);
printf("err\n");
exit(1);
default:
sleep(1);
}
return 0;
}
这是我的主程序。程序 myfile 如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <unistd.h>
int main(int argc, char *argv[]){
printf("Hi!\n");
return 0;
}
这是我期待的输出:
Everything ok...
Hi!
但我只得到:
Everything ok...
我做错了什么? execv 有两个参数,但在我的例子中第二个参数是空的(或 NULL?)。我试图添加行
char *argv[] = NULL;
到我的主程序,但我得到了错误,因为我不能在 C 中这样做。
如果没有终止换行符, 您的程序 和 中的任何一个的输出都不能保证如您预期的那样出现。始终输出终止 '\n'
.
execv
有两个参数,根据手册页,第二个参数需要是:
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.
所以你应该有这样的东西:
char *argv_for_program[] = { filename, NULL };
execv(filename, argv_for_program);
一些其他注意事项:
紧接在 execv
之前的 printf
没有以换行符结尾。由于 stdout
通常是 line buffered,因此在刷新缓冲区之前不会打印文本 "Everything ok..."
。 execv
用 ./myfile
替换了你的程序,没有刷新缓冲区,所以 "Everything ok..."
消息丢失了。要解决此问题,请改为打印 "Everything ok...\n"
,或在 execv
.
之前调用 fflush(stdout)
execv
仅 returns 如果您 未能 执行该程序。在这种情况下,exit(EXIT_SUCCESS)
可能是不可取的;最好打印一条适当的错误消息(例如 perror
)并以失败代码退出。
如评论中所述,您需要 #include <unistd.h>
.
如果您想通过 argv[]
提供参数(正如您在评论中指出的那样),只要您提供 Full-Path 到 运行 的程序作为第一个参数和此后传递给该程序的任何参数。 argv
已经是一个指针数组,最后一个用户提供的参数后的第一个指针设置为 NULL
。您只需在 argv[1]
处开始索引(argv[0]
始终是当前程序 运行,argv[1]
第一个用户提供的参数)您可以做一些简单的事情:
#include <stdio.h>
#include <unistd.h>
int main (int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "error: insufficient input.\n"
"usage: %s full-path-prog [arg1, arg2, ...]\n", argv[0]);
return 1;
}
execv (argv[1], &argv[1]); /* call execv with argv[] */
}
(注意:成功时,execv
不return,新进程替换当前进程,失败时,你实际上应该调用_exit();
如果你设置了 atexit()
函数或析构函数,则避免极端情况 UB -- 此处不相关)
只要您提供有效的实用程序名称和参数(不包括任何重定向等),代码就会将实用程序简单地传递给 execv
,并且它将使用提供的任何其他参数执行, 例如
例子Use/Output
提供程序的完整路径和任何参数,例如
$ ./bin/execv_simple /bin/ls -al /home/david/tmp
total 1163032
drwxr-xr-x 44 david david 20480 Mar 23 13:35 .
drwxr-xr-x 68 david david 4096 Mar 25 02:36 ..
drwxr-xr-x 2 david david 4096 Nov 7 22:30 .qt
-rw-r--r-- 1 david david 4534793 Nov 4 19:31 .xsession-errors
...
$ ./bin/execv_simple /usr/bin/df -h
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 4043708 0 4043708 0% /dev
tmpfs 4055092 11964 4043128 1% /dev/shm
tmpfs 4055092 1716 4053376 1% /run
tmpfs 4055092 0 4055092 0% /sys/fs/cgroup
/dev/sdb2 41156156 25400864 13641604 66% /
tmpfs 4055092 60 4055032 1% /tmp
/dev/sdb3 437217592 43731284 392581260 11% /home
tmpfs 811016 8 811008 1% /run/user/1000
$ ./bin/execv_simple /usr/bin/free
total used free shared buff/cache available
Mem: 8110188 2147572 4048728 53432 1913888 5594460
Swap: 2103292 0 2103292
(注意: 您可以使用 命令替换 和 type -p
或 which
来提供完整的程序名称,例如 ./bin/execv_simple $(type -p free)
将为您填写完整路径信息)
未提供参数:
$ ./bin/execv_simple
error: insufficient input.
usage: ./bin/execv_simple full-path-prog [arg1, arg2, ...]
检查一下,如果您还有其他问题,请告诉我。
我想从我的主程序中使用 fork 来创建我编写的其他程序的进程实例。 这是我正在尝试做的事情的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
int main(int argc, char *argv[]){
char *ar[] = {"./myfile",NULL};
switch (fork()) {
case -1:
printf("Problem.\n");
break;
case 0:
printf("Everything ok...\n");
execv("./myfile",ar);
printf("err\n");
exit(1);
default:
sleep(1);
}
return 0;
}
这是我的主程序。程序 myfile 如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <unistd.h>
int main(int argc, char *argv[]){
printf("Hi!\n");
return 0;
}
这是我期待的输出:
Everything ok...
Hi!
但我只得到:
Everything ok...
我做错了什么? execv 有两个参数,但在我的例子中第二个参数是空的(或 NULL?)。我试图添加行
char *argv[] = NULL;
到我的主程序,但我得到了错误,因为我不能在 C 中这样做。
如果没有终止换行符, 您的程序 和 中的任何一个的输出都不能保证如您预期的那样出现。始终输出终止 '\n'
.
execv
有两个参数,根据手册页,第二个参数需要是:
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.
所以你应该有这样的东西:
char *argv_for_program[] = { filename, NULL };
execv(filename, argv_for_program);
一些其他注意事项:
紧接在
execv
之前的printf
没有以换行符结尾。由于stdout
通常是 line buffered,因此在刷新缓冲区之前不会打印文本"Everything ok..."
。execv
用./myfile
替换了你的程序,没有刷新缓冲区,所以"Everything ok..."
消息丢失了。要解决此问题,请改为打印"Everything ok...\n"
,或在execv
. 之前调用 execv
仅 returns 如果您 未能 执行该程序。在这种情况下,exit(EXIT_SUCCESS)
可能是不可取的;最好打印一条适当的错误消息(例如perror
)并以失败代码退出。如评论中所述,您需要
#include <unistd.h>
.
fflush(stdout)
如果您想通过 argv[]
提供参数(正如您在评论中指出的那样),只要您提供 Full-Path 到 运行 的程序作为第一个参数和此后传递给该程序的任何参数。 argv
已经是一个指针数组,最后一个用户提供的参数后的第一个指针设置为 NULL
。您只需在 argv[1]
处开始索引(argv[0]
始终是当前程序 运行,argv[1]
第一个用户提供的参数)您可以做一些简单的事情:
#include <stdio.h>
#include <unistd.h>
int main (int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "error: insufficient input.\n"
"usage: %s full-path-prog [arg1, arg2, ...]\n", argv[0]);
return 1;
}
execv (argv[1], &argv[1]); /* call execv with argv[] */
}
(注意:成功时,execv
不return,新进程替换当前进程,失败时,你实际上应该调用_exit();
如果你设置了 atexit()
函数或析构函数,则避免极端情况 UB -- 此处不相关)
只要您提供有效的实用程序名称和参数(不包括任何重定向等),代码就会将实用程序简单地传递给 execv
,并且它将使用提供的任何其他参数执行, 例如
例子Use/Output
提供程序的完整路径和任何参数,例如
$ ./bin/execv_simple /bin/ls -al /home/david/tmp
total 1163032
drwxr-xr-x 44 david david 20480 Mar 23 13:35 .
drwxr-xr-x 68 david david 4096 Mar 25 02:36 ..
drwxr-xr-x 2 david david 4096 Nov 7 22:30 .qt
-rw-r--r-- 1 david david 4534793 Nov 4 19:31 .xsession-errors
...
$ ./bin/execv_simple /usr/bin/df -h
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 4043708 0 4043708 0% /dev
tmpfs 4055092 11964 4043128 1% /dev/shm
tmpfs 4055092 1716 4053376 1% /run
tmpfs 4055092 0 4055092 0% /sys/fs/cgroup
/dev/sdb2 41156156 25400864 13641604 66% /
tmpfs 4055092 60 4055032 1% /tmp
/dev/sdb3 437217592 43731284 392581260 11% /home
tmpfs 811016 8 811008 1% /run/user/1000
$ ./bin/execv_simple /usr/bin/free
total used free shared buff/cache available
Mem: 8110188 2147572 4048728 53432 1913888 5594460
Swap: 2103292 0 2103292
(注意: 您可以使用 命令替换 和 type -p
或 which
来提供完整的程序名称,例如 ./bin/execv_simple $(type -p free)
将为您填写完整路径信息)
未提供参数:
$ ./bin/execv_simple
error: insufficient input.
usage: ./bin/execv_simple full-path-prog [arg1, arg2, ...]
检查一下,如果您还有其他问题,请告诉我。