为什么用户的输入会在终端上回显?

时间:2016-06-25 14:06:53

标签: c linux sockets select

我正在尝试使用beej中的select()来理解程序。

当我按下某个键时,程序会打印“按下了一个键”。但是,程序退出后,同一个键在终端上回显,我收到错误“Command not found”。为什么按下的键被回显到终端?

源代码:

/*
 * select.c demo
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

#define STDIN 0

int main(int argc, char *argv[]){
    struct timeval tv;
    fd_set readfds;

    tv = (struct timeval){0};
    tv.tv_sec = 2;
    tv.tv_usec = 5000000;

    FD_ZERO(&readfds);
    FD_SET(STDIN, &readfds);

    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;
}

输出:

shilpa@shilpa-VirtualBox:Socket_Programming$
shilpa@shilpa-VirtualBox:Socket_Programming$ ./select 
f
A key was pressed
shilpa@shilpa-VirtualBox:Socket_Programming$ f
f: command not found

2 个答案:

答案 0 :(得分:1)

您的程序不会消耗其stdin中的任何内容。 它仅检查从stdin读取是否会在分配的时间内成功。 因此,就输入消耗而言,其行为如下:

$ sleep 2.5 

如果你运行它并输入f<enter>,那么使用默认的终端设置(可以用stty控制)它会得到回应(终端通常会回显你键入的所有内容,除非你关掉它,例如,密码输入),然后在sleep终止时,你的shell接收它。然后shell执行shell的操作 - 尝试执行它。这失败,导致command not found错误消息。

答案 1 :(得分:0)

简而言之 - 您没有从程序中的终端读取任何内容。你只是等待准备阅读。详细说明如下。

<强>详情

主要问题如何从您的程序输出到终端程序(如konsole或xterm等)以及您按下的键如何进入您的程序。

简而言之,有两个绑定设备:

  1. 终端主站 - 终端程序使用此设备显示正在运行的程序的结果
  2. 终端从属设备 - 某些程序(如bash)使用此设备。
  3. stdin是程序中绑定到终端从设备的文件描述符。

    当您按下终端程序中的键时(我跳过与终端主机特定内容相关的一些步骤,如termios):

    • 此符号将写入终端主设备
    • 终端主设备将符号传递给终端从设备
    • 终端从设备切换到准备读取状态
    • stdin文件描述符将状态更改为&#34;准备好读取&#34;
    • 选择完成并且您的程序写入&#34;按下了一个键&#34;
    • 您的程序已完成(它无法从设备读取任何内容)
    • shell程序开始从终端从站读取(因为它已准备好读取)并接收输入&#34; f&#34;并输入
    • shell程序解释f并输入作为开始程序&#34; f&#34;