您需要消耗管道。管道连接到什么(换句话说,谁在使用它?)。
如果看起来确实如此,您对输出根本不感兴趣,只需重定向到 null 设备:
作为旁注,我会强烈劝阻using namespace boost::process,因为它看起来像你正在做的。该命名空间中有许多名称很容易与 C/标准库名称发生冲突。例如,pipe 是局部变量吗?是boost::process::pipe这个类型吗?是POSIX系统库调用::pipe吗?
修复
Live On Coliru
#include <boost/process.hpp>
#include <iostream>
int main()
{
namespace bp = boost::process;
std::string cmd = "cat", param = "/etc/dictionaries-common/words";
//bp::pipe pipe;
int return_code = -1;
try {
bp::child cp(cmd + " " + param, (bp::std_out & bp::std_err) > bp::null);
cp.wait();
return_code = cp.exit_code();
} catch (bp::process_error const& e) {
return_code = -1;
}
std::cout << "return_code: " << return_code << "\n";
return return_code;
}
请注意,它在 Coliru 上返回 1,因为该字典不存在。在我的系统上它正确返回0(没有阻塞。
安全
请注意,将命令拼凑成字符串可能非常容易出错并引发安全漏洞(如果传入的文件名是“foot.txt; rm -rf *”怎么办?)。
我建议使用参数向量样式:
std::string cmd = "cat";
std::vector<std::string> params{"-n", "--",
"/etc/dictionaries-common/words"};
bp::child cp(bp::search_path(cmd), params,
(bp::std_out & bp::std_err) > bp::null);
不使用search_path 更安全,但它要求exe 是完全指定的路径(如/bin/cat 或./bin/myexe)。
请注意,现在接受来自外部输入的文件名已经足够安全了:
std::vector<std::string> params{"-n", "--"};
params.insert(end(params), argv + 1, argv + argc);
作为画龙点睛的一笔,让我们关闭子进程的标准输入(这样我们就不会在那里泄露隐私,如果命令行上没有列出文件也不会挂起......):
Live On Coliru
#include <boost/process.hpp>
#include <iostream>
int main(int argc, char** argv)
{
namespace bp = boost::process;
int return_code = -1;
try {
std::string cmd = "/bin/cat";
std::vector<std::string> params{"-n", "--"};
params.insert(end(params), argv + 1, argv + argc);
bp::child cp(cmd, params, //
bp::std_in.close(), //
(bp::std_out & bp::std_err) > bp::null);
cp.wait();
return_code = cp.exit_code();
} catch (bp::process_error const& e) {
return_code = -1;
}
std::cout << "return_code: " << return_code << "\n";
return return_code;
}
现在它打印return_code: 0,因为文件实际上存在于 Coliru 上。