实现带超时的wget下载时,如何屏蔽pgrep系统调用的输出?
解决wget超时检查中pgrep输出PID的问题
你遇到的问题本质是:system()函数会把执行命令的标准输出和错误输出默认转发到当前进程的控制台,而pgrep wget在找到进程时会打印出对应的PID,所以每次循环都会看到这个输出。下面给你两个简单的解决办法:
方法1:重定向pgrep的输出到/dev/null
这是最直接的方案,只需要修改pgrep命令,把它的所有输出(标准输出+标准错误)都重定向到系统的"黑洞设备"/dev/null,这样就不会有任何内容打印到控制台了,同时system()的返回值依然能正确反映pgrep的执行结果(找到wget进程返回0,没找到返回非0)。
修改你的代码中调用pgrep的那一行:
activeWget = system("pgrep wget > /dev/null 2>&1");
> /dev/null:将命令的标准输出(stdout)丢弃2>&1:将标准错误(stderr)重定向到和标准输出相同的位置,也就是一起丢弃
修改后的完整代码示例:
std::string systemCall{}; systemCall = "wget " + downloadLink + " &"; system(systemCall.c_str()); time_t timer_old, timer_current; time(&timer_old); int activeWget = 0; do { time(&timer_current); // 补上循环内更新当前时间的步骤,原代码漏了这一步会导致超时判断失效 activeWget = system("pgrep wget > /dev/null 2>&1"); } while ((activeWget == 0) && (difftime(timer_current, timer_old) < 3));
方法2:使用popen替代system(更灵活的控制)
如果你需要对命令输出做更多自定义处理,而不仅仅是丢弃,可以用popen()函数,它能让你直接读取命令的输出,然后自行决定是否打印。不过对于你的场景来说,方法1已经足够简单高效了,这里只做简单示例:
#include <cstdio> // ... 其他代码 ... do { time(&timer_current); FILE* pipe = popen("pgrep wget", "r"); if (pipe) { // 读取输出但不打印,直接丢弃 char buffer[128]; while (fgets(buffer, sizeof(buffer), pipe) != nullptr) { // 此处无操作,忽略输出内容 } activeWget = pclose(pipe); // pclose的返回值对应命令的退出状态 } else { // 处理popen调用失败的情况 activeWget = -1; } } while ((activeWget == 0) && (difftime(timer_current, timer_old) < 3));
内容的提问来源于stack exchange,提问作者Sicoe Mircea
相关产品推荐
相关产品推荐

