【问题标题】:fgets() doesn't work after popen()fgets() 在 popen() 之后不起作用
【发布时间】:2014-12-08 21:27:46
【问题描述】:

我正在尝试使用 system() 命令从 c 程序启动“vlc”。命令执行后,我正在执行 popen() 和 fgets() 函数来获取已经启动的 vlc 应用程序的 PID。但是 fgets() 没有给出 PID。代码如下。它从“根”运行。 vlc 是从另一个名为“sam”的用户帐户启动的,因为 vlc 不能从 root 启动。

char arrcCommand[2048] = {0};
char arrcGetPIDCommand[1024] = {0};
char arrcPID[1024] = {0};
int iStatus = 0;

/*User 'sam' was added previously*/
sprintf (arrcCommand, "sudo -u sam vlc -q -I dummy /media/video.mp4 --sout '#transcode{vcodec=h264,vb=16,fps=1,scale=Auto,acodec=mpga,ab=128,channels=2,samplerate=44100}:rtp{dst=232.0.0.1,port=927,mux=ts,ttl=1}' >/dev/null 2>&1 &");

iStatus = system(arrcCommand);

sprintf(arrcGetPIDCommand, "sudo -u sam ps axu | grep vlc | grep port=927 | grep -v sudo | awk '{print $2}'");
FILE* pFp = popen(arrcGetPIDCommand, "r");
if(pFp == NULL)
{
    return -1;
}
if( fgets(arrcPID, sizeof(arrcPID), pFp) != NULL )
{
    printf("\n%d\n", atoi(arrcPID));
} 
else
{
    iRetVal = -1;
    return iRetVal;
}

pclose(pFp);

注意:这段代码 sn-p 在单独的 c 程序中运行良好。但它在我的实际代码库中不起作用,该代码库非常大,并且其他 popen() 函数也被多次调用。我无法理解这个问题。请帮我。

【问题讨论】:

  • 天哪,这是一种复杂的方式来做你想做的事情。
  • 为什么不使用fork()execvp()?父进程会直接知道它的子进程是什么;您可以在孩子中进行 I/O 重定向;你根本不需要ps 命令等,也不需要管道等。
  • 对不起,我没有正确理解。这样,我就会得到子进程的pid。但是如何获取 vlc 应用程序的 pid 呢?你能解释一下吗?

标签: c fork vlc popen fgets


【解决方案1】:

如果您将echo $! 添加到您的system 命令中,这将打印后台进程PID,您可以让生活更轻松,那么您不需要为它使用grep。当然,这意味着使用 popen() 代替该命令来读取 PID。

【讨论】:

  • 对不起,我没能得到它。可以举个例子吗?
  • popen("sudo -u sam vlc ... &; echo $!") 然后从管道中读取以获取后台 PID。没有更多的system()
  • 谢谢。我试过了,但这给出了语法错误: sh: -c: line 0: syntax error near unexpected token `;'如果您在普通命令行中触发该命令,也会出现语法错误。
  • 抱歉,不应该添加;。只需"sudo -u sam vlc ... & echo $!"
  • 非常感谢。它完美地工作。我也解决了我的问题。当我用 gdb 调试它时,问题就出现了。 gdb 可能使用了读取缓冲区。通常它工作得很好。
猜你喜欢
  • 2018-01-02
  • 2013-10-22
  • 2021-12-17
相关资源
最近更新 更多