检测按键
编写过MS-DOS程序的人通常都会查找Linux下等同于kbhit的函数,这个函数会检测一个按键是否被按下而并不实际的读取。不幸的是他们并没有找到这样的函数,因为并没有直接等同的函数。Unix程序员并不会注意到这个遗漏,因为Unix的编程方式通常为程序应准备好等待事件的发生。因为这就是通常的kbhit的用法,所以Unix和Linux将其忽略了。
然而,当我们要由MS-DOS移植程序时,通常需要模拟kbhit,此时我们可以用非正规输入模式来做到。
试验--我们自己的kbhit1 首先我们需要定义标准的头文件并且为终端设置声明了一个结构。peek_character用于测试一个按键是否被按下。然后我们定义了我们将会用到的函数的原型。
#include <stdio.h>
#include <termios.h>
#include <term.h>
#include <curses.h>
#include <unistd.h>
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard();
void close_keyboard();
int kbhit();
int readch();
2 main函数调用init_keyboard函数来配置终端,然后一秒循环一次,调用kbhit函数。如果按键检测为q,close_keyboard函数会返回正常行为并且退出程序。
int main()
{
int ch = 0;
init_keyboard();
while(ch != ‘q’) {
printf(“looping\n”);
sleep(1);
if(kbhit()) {
ch = readch();
printf(“you hit %c\n”,ch);
}
}
close_keyboard();
exit(0);
}
3 init_keyboard与close_keyboard在程序的开始和结束配置终端。
void init_keyboard()
{
tcgetattr(0,&initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
void close_keyboard()
{
tcsetattr(0, TCSANOW, &initial_settings);
}
4 下面是检测键盘按键的函数:
int kbhit()
{
char ch;
int nread;
if(peek_character != -1)
return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0,&ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1) {
peek_character = ch;
return 1;
}
return 0;
}
5 按下的按键是由下一个函数,readch,读取的,然后将peek_character为下一次循环设置为-1。
int readch()
{
char ch;
if(peek_character != -1) {
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,&ch,1);
return ch;
}
当我们运行这个程序时,我们会得到下面的输出:
$ ./kbhit
looping
looping
looping
you hit h
looping
looping
looping
you hit d
looping
you hit q
$
工作原理在init_keyboard中配置终端在返回之前(MIN=1,TIME=0)读取一个字符。kbhit将其改变为检测输入并且立即返回(MIN=0,TIME=0),然后在程序退出前恢复原始设置。
注意,我们必须读取被按下的键,但是却是在局部存储,从而可以在需要的时候返回。
虚拟控制台
Linux提供了一个称之为虚拟控制台的特性。有许多的终端设备可用,所有的设备都共享PC的屏幕,键盘以及鼠标。通常,一个Linux的安装配置12个这样的虚拟控制台。
虚拟控制台是通过字符设备/dev/ttyN来访问的,在这里N是一个数字,由1开始。
如果我们的Linux系统使用文本登陆,那么在Linux启动运行时我们就会得到一个登陆提示。然后我们可以使用用户名与密码进行登陆。此时我们使用的设备就是第一个虚拟控制台,终端设备/dev/tty1。
使用who与ps命令,我们可以看到登陆的用户,shell与在这个虚拟控制台上正运行的程序:
$ who
neil tty1 Mar 8 18:27
$ ps -e
PID TTY TIME CMD
1092 tty1 00:00:00 login
1414 tty1 00:00:00 bash
1431 tty1 00:00:00 emacs
从这里我们可以看出登陆的用户为neil,并且在控制台设备/dev/tty1上运行Emacs。
Linux通常启动一个getty进程运行在前六个虚拟控制台上,这样就可以使用相同的屏幕,键盘与鼠标登陆六次。我们可以使用ps看到这些进程:
$ ps -e
PID TTY TIME CMD
1092 tty1 00:00:00 login
1093 tty2 00:00:00 mingetty
1094 tty3 00:00:00 mingetty
1095 tty4 00:00:00 mingetty
1096 tty5 00:00:00 mingetty
1097 tty6 00:00:00 mingetty
在这里我们可以看到SuSE默认的getty程序,mingetty,运行在另外五个虚拟控制台上,等待用户登陆。
我们可以使用一个特殊的按键组合Ctrl+Alt+F<N>来在虚拟控制台之间进行切换,在这里N为我们要切换到的虚拟控制台号。所以要切换到第2个虚拟控制台,我们需要按下Alt+Ctrl+F2,而Ctrl+Alt+F1会返回到第一个控制台。(当由字符登陆而不是图形登陆切换时,Ctrl+F<N>组合也可以起作用)
如果Linux启动一个图形登陆,或者是通过startx或者是通过一个显示管理器,例如xdm,X Window系统将会使用第一个空闲的虚拟控制台来启动登陆,通常为/dev/tty7。当使用X Window系统时,我们可以使用Ctrl+Alt+F<N>切换到文本控制台,并使用Ctrl+Alt+F7返回到图形控制台。
通常在Linux上会运行多个会活。如果我们这样做,例如,使用命令
$ startx - :1
Linux会在下一个空闲的虚拟控制台上启动X服务器,在这种情况下,通常为/dev/tty8,然后我们可以使用Ctrl+Alt+F8与Ctrl+Alt+F7在他们之间进行切换。
在所有其他方面,虚拟控制台的行为与终端类似,正如我们在这一章所描述的。如果一个进程具有正确的权限,虚拟控制台可以使用与通常的终端相的方式执行打开,读取与写入等操作。
伪终端许类Unix系统,包括Linux,具有一个名为伪终端的特性。这些设备的行为与我们在这一章所使用的终端相类似,所不同的是他们并没有与其相关联的硬件。他们可以用来为其他的程序提供一个类终端接口。
例如,使用两个伪终端就可以使得两个象棋程序彼此交战,尽管程序本身是设置用来与人在终端进行交互的。作为中介的程序将一个程序的动作传递给另一个。可以使得伪终端可以使得程序在不提供终端的情况下像通常一样运行。
伪终端曾经是以特定系统的方式实现的。现在他们已经进入Single Unix规范的Unix98伪终或是PTY标准中。
总结在这一章,我们了解了控制终端的三个不同方面。在这一章的第一部分,我们了解了重定向检测以及如何与一个终端交互,尽管标准的文件描述符已经进行重定向。我们讨论的硬件模型及其历史。然后我们了解了通用终端接口以及在Linux终端处理上提供详细控制的termios结构。我们也看到了如何使用termios数据库以及以独立于终端的方式管理屏幕的相关函数,同时我们也了解了立即检测按键。最后,我们讨论了Linux虚拟控制台以及伪终端。
分享到:
相关推荐
linux 终端 linux 终端 操作工具
### Linux终端的设计与应用 #### 引言 随着信息技术的快速发展和全球化的加深,Linux作为一款开源的操作系统,正受到越来越多国家政府和大型跨国公司的关注。特别是在金融、海关、铁路、证券、航空、图书馆等领域...
这款工具以其直观的图形界面、丰富的功能以及与Linux终端的无缝集成,成为了许多IT专业人员的首选。 **1. WinSCP的主要功能** - **文件传输**:WinSCP支持断点续传、批量传输和同步传输,使得在Linux服务器间移动...
Linux 终端登录实验 Linux 终端登录实验是 Unix 操作系统的基础实验之一,本实验旨在让学生掌握 Linux 终端的基本操作,包括登录系统、使用 shell、创建新用户、切换虚拟终端等。 一、实验准备 在进行 Linux 终端...
Linux 终端实用技巧篇 本篇文章将详细介绍 Linux 终端中的实用技巧和命令,旨在帮助用户更好地掌握 Linux 终端的使用。以下是文章中的知识点总结: 一、基本命令 * Tab 键组合:在终端输入命令时,可以使用 Tab ...
Linux终端快捷键是提高操作效率的重要工具,尤其对于系统管理员和需要频繁使用命令行的用户来说,掌握它们可以显著提升工作效率和操作精准度。Linux系统自诞生以来,其命令行界面一直以其强大的灵活性和控制能力被...
Linux终端下的直接写屏技术Linux终端下的直接写屏技术Linux终端下的直接写屏技术
特别是在基于ARM处理器的嵌入式Linux终端系统领域,随着系统复杂度的增加和应用需求的提升,性能优化已经成为系统设计中的重要课题。本文针对基于ARM的嵌入式Linux终端系统的性能实时优化进行深入探讨,并提出了一套...
解码器用的是神器ffmpeg,所以在终端下可以播放大部分视频,图片,动态图片。使用时改变终端的字体大小,行数,列数,最大行数,最大列数可调节观看效果。播放器有两种播放模式,默认灰度播放,输入1使能颜色播放。...
宁盾多因子认证(MFA)与Linux终端安全认证方案.pdf宁盾多因子认证(MFA)与Linux终端安全认证方案.pdf宁盾多因子认证(MFA)与Linux终端安全认证方案.pdf宁盾多因子认证(MFA)与Linux终端安全认证方案.pdf宁盾多因子认证...
很实用的linux 终端和颜色控制说明,觉得还不错,拿出来分享一下。
linux终端常用命令总结,有需要或者忘记的可以看一下。
《SecureCRT:Linux终端仿真软件详解》 在IT领域,特别是Linux系统管理中,终端仿真软件扮演着至关重要的角色。SecureCRT是一款广受欢迎的终端模拟器,尤其在Windows平台上,它为用户提供了与Linux和Unix服务器进行...
这是一个txt的文本文件,主要总结了一些常见linux终端的快捷的使用。
Linux超级终端,也被称为控制台或TTY(Teletype),是Linux系统中一个重要的命令行界面,用于远程或本地访问操作系统。它为用户提供了一个与操作系统交互的文本接口,允许用户执行各种系统管理任务,如运行命令、...
### Linux终端设置详解 在日常使用Linux的过程中,用户往往希望能够个性化自己的系统,使其不仅功能强大而且界面友好。本文将详细介绍如何对Linux终端进行个性化设置,包括改变终端的提示符、字体颜色等内容,让...
在Linux终端中,我们经常看到诸如`pip install`或`curl`等命令在执行时会显示带有进度条的输出,这极大地提升了用户交互体验。在本教程中,我们将探讨如何使用Golang语言来实现类似的功能,即在Linux终端中创建一个...
本教程将详细讲解如何使用C#通过SSH(Secure Shell)协议来调用Linux终端并实现文件上传。 SSH是一种网络协议,用于安全地远程登录到Linux或Unix服务器,执行命令,以及传输文件。C#中可以借助第三方库,如SSH.NET...
【向Linux终端服务器迁移】 Linux操作系统以其开源、稳定和低成本的特性,在企业级应用中越来越受欢迎。本文将探讨如何通过K-12LTSP(Linux Terminal Server Project)软件包,帮助小型公司或学校实验室快速迁移至...