Linux C select:管道回显输入有效,但从键盘读取无效?
我试图理解 http://beej.us/guide/bgnet/examples/select .c(包含在下面供参考)。我正在这样做:
:~$ cat /etc/issue
Ubuntu 10.04 LTS \n \l
:~$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
:~$ wget http://beej.us/guide/bgnet/examples/select.c
:~$ gcc select.c -o select
:~$ echo "ff" | ./select
A key was pressed!
:~$ ./select
TYPINGTYTimed out.
因此,选择程序显然将回声管道识别为输入;但它不会识别终端上的按键。这是为什么呢?是否可以使用某种重定向(我猜,类似于屏幕如何将键盘输入“重定向”到串行会话)以便识别终端中的实际按键?
select.c:
/*
** select.c -- a select() demo
*/
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define STDIN 0 // file descriptor for standard input
int main(void)
{
struct timeval tv;
fd_set readfds;
tv.tv_sec = 2;
tv.tv_usec = 500000;
FD_ZERO(&readfds);
FD_SET(STDIN, &readfds);
// don't care about writefds and exceptfds:
select(STDIN+1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(STDIN, &readfds))
printf("A key was pressed!\n");
else
printf("Timed out.\n");
return 0;
}
编辑:参见答案;因此我们需要的只是按 Enter 键:
:~$ ./select
A key was pressed!
或者我们可以使用 stty raw 关闭缓冲输入(并使用 stty Cooked 将其重新打开):
:~ stty raw
:~ ./select
dA key was pressed!
:~ stty cooked
I am trying to understand http://beej.us/guide/bgnet/examples/select.c (included below for reference). I am doing this:
:~$ cat /etc/issue
Ubuntu 10.04 LTS \n \l
:~$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
:~$ wget http://beej.us/guide/bgnet/examples/select.c
:~$ gcc select.c -o select
:~$ echo "ff" | ./select
A key was pressed!
:~$ ./select
TYPINGTYTimed out.
So, the select program apparently recognizes an echo piping into it as input; but it will not recognize keypresses on the terminal. Why is this? Can some sort of redirection be used (I guess, similar to how screen could 'redirect' keyboard input to a serial session) so that actual key presses in terminal are recognized?
select.c:
/*
** select.c -- a select() demo
*/
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define STDIN 0 // file descriptor for standard input
int main(void)
{
struct timeval tv;
fd_set readfds;
tv.tv_sec = 2;
tv.tv_usec = 500000;
FD_ZERO(&readfds);
FD_SET(STDIN, &readfds);
// don't care about writefds and exceptfds:
select(STDIN+1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(STDIN, &readfds))
printf("A key was pressed!\n");
else
printf("Timed out.\n");
return 0;
}
Edit: see answer; thus all we need is to press enter:
:~$ ./select
A key was pressed!
or we can turn off buffered input with stty raw
(and turn it back on with stty cooked
):
:~ stty raw
:~ ./select
dA key was pressed!
:~ stty cooked
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
标准输入是缓冲流。 select() 调用将无法检测到有可用的输入,直到在输入末尾命中换行符。您不能像这样使用 select() 来读取各个击键。
Standard input is a buffered stream. The select() call will not be able to detect that there is input available until the newline is hit at the end of the input. You can't use select() like this to read individual keystrokes.