Linux C select:管道回显输入有效,但从键盘读取无效?

发布于 2024-08-31 16:41:56 字数 1496 浏览 2 评论 0原文

我试图理解 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

掩于岁月 2024-09-07 16:41:56

标准输入是缓冲流。 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文