Qt 为什么从STDOUT阅读有用?
我遇到了一个奇怪的情况,在终端中运行程序时,从标准输出读取数据是有效的。问题是,为什么和如何?让我们从代码开始:Qt 为什么从STDOUT阅读有用?,qt,unix,stdout,stdin,pty,Qt,Unix,Stdout,Stdin,Pty,我遇到了一个奇怪的情况,在终端中运行程序时,从标准输出读取数据是有效的。问题是,为什么和如何?让我们从代码开始: #include <QCoreApplication> #include <QSocketNotifier> #include <QDebug> #include <QByteArray> #include <unistd.h> #include <errno.h> int main(int argc, ch
#include <QCoreApplication>
#include <QSocketNotifier>
#include <QDebug>
#include <QByteArray>
#include <unistd.h>
#include <errno.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
const int fd_arg = (a.arguments().length()>=2) ? a.arguments().at(1).toInt() : 0;
qDebug() << "reading from fd" << fd_arg;
QSocketNotifier n(fd_arg, QSocketNotifier::Read);
QObject::connect(&n, &QSocketNotifier::activated, [](int fd) {
char buf[1024];
auto len = ::read(fd, buf, sizeof buf);
if (len < 0) { qDebug() << "fd" << fd << "read error:" << errno; qApp->quit(); }
else if (len == 0) { qDebug() << "fd" << fd << "done"; qApp->quit(); }
else {
QByteArray data(buf, len);
qDebug() << "fd" << fd << "data" << data.length() << data.trimmed();
}
});
return a.exec();
}
下面是4次执行的输出:
$ ./stdoutreadtest 0 # input from keyboard, ^D ends, works as expected
reading from fd 0
typtyptyp
fd 0 data 10 "typtyptyp"
fd 0 done
所以,问题是,到底发生了什么,为什么上面的最后两次运行实际上读取了终端上键入的内容
我还试着查看QSocketNotifier源代码,但没有获得任何见解。fd 0、1、2之间没有区别,所有三个fd都指向终端如果没有重定向,它们完全相同 程序通常使用0作为输入,1作为输出,2作为错误,但它们都可以是不同的方式 例如,对于
less
,普通用法:
prog | less
现在less
的输入被重定向到prog
,并且less
无法从stdin
读取任何用户输入,那么less
如何获得用户输入,如向上/向下滚动或向上/向下翻页
当然less
可以从stdout读取用户输入,这正是less
所做的
因此,当您知道bash如何处理这些FD时,可以明智地使用这些FD。请查看/proc/$pid/fds/-1中的符号链接,如果您不做其他操作,则它只是TTY的符号链接
$ echo pipe | ./stdoutreadtest 0 # input from pipe, works as expected
reading from fd 0
fd 0 data 5 "pipe"
fd 0 done
$ ./stdoutreadtest 1 # input from keyboard, ^D ends, works!?
reading from fd 1
typtyp
fd 1 data 7 "typtyp"
fd 1 done
$ echo pipe | ./stdoutreadtest 1 # input from pipe, still reads keyboard!?
reading from fd 1
typtyp
fd 1 data 7 "typtyp"
fd 1 done
prog | less