[英]Read cout and write to cin of a process with boost::process
我正在尝试生成一个shell并读取stdout和stderr,并让用户通过写入stdin来运行命令。 我似乎无法从stdout或stderr读取内容,并且向stdin写入内容显然也无济于事。
如果我不尝试重定向任何stdin,stdout或stderr,它将生成一个正常的shell,就像我期望的那样。 但是,重定向它们只会使一切消失。 >>
只是神秘地挂起。 我从孩子的标准输出中取出,然后将其放回实际的标准输出中,因此我希望至少可以显示类似用户名的内容,但是就像我说的那样,它只是阻塞了,因为缓冲区中肯定没有任何内容。
boost::process::child shell;
boost::process::opstream instream;
boost::process::ipstream errstream;
boost::process::ipstream outstream;
void console_out_read()
{
char ch;
do
{
outstream >> ch;
std::cout << ch;
}
while(true);
}
void console_err_read()
{
char ch;
do
{
errstream >> ch;
std::cerr << ch;
}
while(true);
}
void console_in_write()
{
int ch;
do
{
std::cin >> ch;
instream << ch;
}
while(true);
}
int main()
{
std::error_code ec;
shell = boost::process::child("bash",
boost::process::std_out > outstream,
boost::process::std_err > errstream,
boost::process::std_in < instream,
ec);
boost::thread cro(console_out_read);
boost::thread cre(console_err_read);
boost::thread cwi(console_in_write);
shell.wait();
return 0;
}
您发布的代码存在几个问题。
首先,在console_in_write
您将ch
声明为int
而不是char
。 这意味着std::cin
将只接受看起来像数字的东西。 如果您输入数字以外的内容,这将导致std::cin
进入错误状态。
其次,即使将ch
更改为char
, std::cin >> ch
也将永远不会读取换行符,因为格式化的输入操作会丢弃空格。 解决此问题的最简单方法是使用std::getline
逐行读取而不是逐字符读取,并在读取的每一行之后仅写入换行符。
第三,boost的管道流被完全缓冲。 这意味着您需要在编写换行符后刷新流,以便将数据发送到子进程。 否则,您将键入命令,并且不会发生任何事情,因为数据仅位于流的缓冲区中。
第四,必须将std::thread
超出范围才能进行join
或detach
。 由于您当前不使用I / O线程,因此子进程退出后,父进程将崩溃。
将所有这些放在一起,我期望一个最小的示例看起来像这样:
boost::process::child shell;
boost::process::opstream instream;
boost::process::ipstream errstream;
boost::process::ipstream outstream;
void console_out_read()
{
std::string line;
while (std::getline(outstream, line))
{
std::cout << line << '\n';
}
}
void console_err_read()
{
std::string line;
while (std::getline(errstream, line))
{
std::cout << line << '\n';
}
}
void console_in_write()
{
std::string line;
while (std::getline(std::cin, line))
{
instream << line << std::endl;
if (line == "exit") return;
}
}
int main()
{
std::error_code ec;
shell = boost::process::child("bash",
boost::process::std_out > outstream,
boost::process::std_err > errstream,
boost::process::std_in < instream,
ec);
std::thread cro(console_out_read);
std::thread cre(console_err_read);
std::thread cwi(console_in_write);
shell.wait();
cro.join();
cre.join();
cwi.join();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.