在 C++ 中使用管道和超时执行命令(并读取标准输出)

Posted

技术标签:

【中文标题】在 C++ 中使用管道和超时执行命令(并读取标准输出)【英文标题】:Executing commands with pipes and timeout in c++ (and reading stdout) 【发布时间】:2012-12-21 01:06:17 【问题描述】:

我需要你的帮助!

我制作了一个报告守护程序(在 c++ 中),它需要定期在服务器上执行一堆命令。

一个简单的示例命令是:“/bin/ps aux | /usr/bin/wc -l”

第一个想法是 fork 一个子进程,该子进程使用 popen() 运行命令,并在父进程中设置一个 alarm(),如果命令尚未退出,则在 5 秒后杀死子进程。

我尝试使用“sleep 20000”作为命令,子进程被杀死但睡眠命令仍在运行......不好。

第二个想法是使用 execlp() 而不是 popen(),它适用于简单的命令(即没有管道),例如“ls -lisa”或“sleep 20000”。我可以得到结果,如果 5 秒后没有完成,进程将被杀死。

现在我需要执行那个“/bin/ps aux | /usr/bin/wc -l”命令,显然它不能直接与 execlp() 一起工作,所以我尝试了那个“hack”:

execlp("sh","sh","-c","/bin/ps aux | /usr/bin/wc -l",NULL);

我工作……或者我想……我试过了

execlp("sh","sh","-c","sleep 20000",NULL); 

为了确定,子进程在 5 秒(我的超时)后被杀死,但睡眠命令只是停留在那里......

我愿意接受建议(我愿意接受黑客攻击)!

提前致谢!

TLDR;

我需要一种方法:

执行“复杂”命令,例如“/bin/ps aux | /usr/bin/wc -l” 得到它的输出 如果超过 5 秒,请确保它被杀死(ps 命令只是示例,实际命令可能会永远挂起)

【问题讨论】:

【参考方案1】:

使用 coreutils 中的timeout 命令:

/usr/bin/timeout 5 /bin/sh -c "/bin/ps aux | /usr/bin/wc -l"

【讨论】:

谢谢!我暂时无法测试,但我回家后会尝试!不过有一件事,用我的解决方案杀死子进程也杀死了“sh -c”,但不知何故,“睡眠 20000”进程设法留下来。 在推荐timeout之前,我测试了它并确保sleep也被终止了。 execlp("timeout","timeout","5","sh","-c","ls -lisa | grep etc",NULL); 可以,谢谢!

以上是关于在 C++ 中使用管道和超时执行命令(并读取标准输出)的主要内容,如果未能解决你的问题,请参考以下文章

在 Qt 4.7 中将标准输出管道传输到 QLabel

[Java]_[初级]_[如何调用外部命令获取输出并设置它的超时退出]

[Java]_[初级]_[如何调用外部命令获取输出并设置它的超时退出]

shell第四篇(上)

使用 ReadFile 异步读取管道

Linux 管道