【发布时间】:2015-09-14 12:52:47
【问题描述】:
我开发了以下函数以便从我的 C 代码中执行 shell 命令
int mycmd(char *cmd, int n, ...)
{
va_list arg;
int i, pid;
static int mycmd_pfds[2];
char *argv[n+2];
argv[0] = cmd;
va_start(arg,n);
for (i=0; i<n; i++)
{
argv[i+1] = va_arg(arg, char*);
}
va_end(arg);
argv[n+1] = NULL;
if (pipe(mycmd_pfds) < 0)
return -1;
if ((pid = fork()) == -1)
return -1;
if (pid == 0) {
/* child */
close(mycmd_pfds[0]);
dup2(mycmd_pfds[1], 1);
close(mycmd_pfds[1]);
execvp(argv[0], (char **) argv);
exit(ESRCH);
} else if (pid < 0)
return -1;
/* parent */
close(mycmd_pfds[1]);
int status;
while (waitpid(pid, &status, 0) != pid);
close(mycmd_pfds[0]);
return 0;
}
此函数适用于像 ls 这样的 linux 命令。但是当我使用此功能启动服务时,它不起作用,然后服务没有启动。
我试过了
mycmd("/etc/init.d/sysntpd", 1, "start");
我也试过了
mycmd("/bin/sh", 2, "/etc/init.d/sysntpd", "start");
两者都不起作用。我在脚本开头添加了echo,我可以看到(带有管道的read)显示了echo消息但服务没有启动。
我错过了什么?如何使服务从我的 C 代码启动? (我应该只打电话给/etc/init.d/sysntpd)。
【问题讨论】:
-
为什么从您的代码中完成而不是让系统自动完成是个好主意?
-
@JonathanLeffler 事实上,我正在使用 C 代码开发数据模型。用户可以在其中要求我的应用程序启动或停止所需的服务。
-
如果
execvp()失败,您可以改进错误报告:将errno或strerror(errno)打印到标准错误。您是否遇到权限问题?您是否以 root 身份运行您的服务?管道是干什么用的? -
@JonathanLeffler 我正在以 root 身份运行我的 c 函数。
-
您尝试运行的服务脚本的开头是否有
#!...?脚本上是否设置了可执行位?