我正在 Linux 上用 C 语言编写一个程序,其中包括一个允许在远程机器上执行 shell 命令的模块。实际执行命令的最简单方法当然是简单地使用 system() 函数,或者使用 popen 然后获取输出。但是,由于与当前问题无关的其他设计要求,我选择使用更底层的方法。
所以基本上,我建立了一个管道和分叉,然后调用 execl。这一切都很完美,除了一个恼人的例外。如果要执行的 shell 命令是一个守护进程,它就不能正常工作。在这种情况下,它只是挂起。我不知道为什么。我的理解是,当守护进程启动时,它通常会分叉,然后父进程退出。由于我的应用程序有一个到父级的开放管道,因此当父级退出时,对 read() 的调用应该会失败。但相反,应用程序只是挂起。
这是一些重现问题的基本代码:
int main(int argc, char** argv)
{
// Create a pipe and fork
//
int fd[2];
int p = pipe(fd);
pid_t pid = fork();
if (pid > 0)
{
// Read from the pipe and output the result
//
close(fd[1]);
char buf[1024] = { 0 };
read(fd[0], buf, sizeof(buf));
printf("%s\n", buf);
// Wait for child to terminate
int status;
wait(&status);
}
else if (pid == 0)
{
// Redirect stdout and stderr to the pipe and execute the shell
// command
//
dup2(fd[1], STDOUT_FILENO);
dup2(fd[1], STDERR_FILENO);
close(fd[0]);
execl("/bin/sh", "sh", "-c", argv[1], 0);
}
}
如果您将其与普通的 shell 命令一起使用,则该代码可以正常工作。但是,如果您尝试运行守护程序,它只会挂起,而不是按应有的方式返回到提示符。