【问题标题】:Why input from user is being echoed on terminal?为什么用户的输入会在终端上回显?
【发布时间】:2016-06-25 14:06:52
【问题描述】:

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

当我按下一个键时,程序会打印“按下了一个键”。但是,程序退出后,终端上会回显相同的键,并且出现错误“找不到命令”。为什么按下的键会回显到终端上?

源代码:

/*
 * 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

【问题讨论】:

  • 请将代码和输出粘贴到此处,作为文本。
  • 好吧,你不是read()ing "key",只是检测输入的可用性。 “key”保留在输入缓冲区中。
  • @FrédéricHamidi :我明白了......但是为什么它会打印在终端(stdout)上?
  • 正如@PSkocik 所说,shell 会看到未读的输入,它的工作是在其命令行上输出它(在 *NIX 上,您可以在命令运行时输入一些内容,并且预期某些内容会在命令完成运行后包含在 shell 的命令行中)。
  • 非常感谢@FrédéricHamidi

标签: c linux sockets select


【解决方案1】:

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

$ sleep 2.5 

如果您运行它并输入f&lt;enter&gt;,那么使用默认终端设置(可通过stty 控制)它会得到回显(终端通常会回显您键入的所有内容,除非您将其关闭,例如密码输入),然后在sleep 终止时重新回显,此时您的shell 会收到它。然后shell 做shell 做的事情——尝试执行它。这会失败,导致出现command not found 错误消息。

【讨论】:

    【解决方案2】:

    简而言之-您没有从程序中的终端读取任何内容。您只需等待阅读准备就绪。详细解释如下。

    详情

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

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

    1. 终端主机-终端程序使用此设备显示程序运行的结果
    2. 终端从站 - 此设备被 bash 等程序使用。

    stdin 是程序中绑定到终端从设备的文件描述符。

    当您在终端程序中按下键时(我跳过了一些与终端主控相关的步骤,例如 termios):

    • 此符号写入终端主设备
    • 终端主设备将符号传递给终端从设备
    • 终端从设备切换到准备读取状态
    • stdin 文件描述符将状态更改为“准备读取”
    • 选择完成,您的程序会写“按下了一个键”
    • 您的程序已完成(它不会从设备读取任何内容)
    • shell 程序开始从终端从机读取(因为它已准备好读取)并接收输入“f”并进入
    • shell 程序解释 f 并输入为启动程序“f”

    【讨论】:

      猜你喜欢
      • 2016-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 2020-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多