终端设备 tty,pty,pts 概念与文件描述符的联系

摘要:
第1节 理解终端设备tty、pty、pts概念简要描述:终端设备默认具有输入、输出功能。每个终端设备接入Linux系统,系统为该终端的输入功能绑定为0的文件描述符,输出功能绑定为1的文件描述符,在处理终端设备发送过来的指令出现错误时,错误提示绑定为2的文件描述符。第3节 终端设备与文件描述符及重定向的默认行为3.1 终端设备与文件描述符及重定向的默认行为默认情况下:系统会帮用户默认补全输入及输出的重定向路径。

1节 理解终端设备ttyptypts概念

理解终端设备tty、pty、pts概念

简要描述:

  • 终端设备默认具有输入、输出功能。
  • 现代我们最常用的接入服务器端的方式(如:ssh通过tcp/ip的方式连接服务器端,作为服务器的终端设备)为服务的接入方式。
  • 但服务器端默认的连接终端为tty模式,(是以串口设备的接入方式,如我们的键盘、显示器),服务器默认提供tty1...tty6共6个终端接口,用Ctrl+Alt+F1...F6切换。
  • 所以在ssh通过tcp/ip连接服务器端的时候,服务器系统会将该服务转换为ptmx设备形态(可以理解为硬件链路)接入服务器端。
  • 同时将该ssh服务fork的子进程转换为pts设备(可以理解为输入输出设备),再用PTY驱动将两个设备绑定起来。

第2节 终端设备与文件描述符fd(file description)及重定向的关系

终端设备 tty,pty,pts 概念与文件描述符的联系第2张

计算机3个组件与文件描述文件描述的数字表示对应文件
存储器磁盘相关3 ~ 65535(终端设备执行)程序所打开磁盘上的文件
输入设备相关0(符号:<或0<)/dev/stdin
输出设备相关1(符号:>或1>)/dev/stdout
错误报告2(符号:2>)/dev/stderr

简要描述:

  1. Linux中一切皆文件,所有的存在都以文件的形式展示出来,文件描述符专用于描述系统调用文件使用情况,为每个打开的文件都打上标识且占用一个文件描述符。
  2. 终端设备与文件描述符及重定向[ >,< ](注意不是追加重定向)不是单独存在,而是相辅相成。  
  3. 重定向主要的作用是数据源流从一个设备流向另一个设备中。(磁盘上的所有类型文件,在概念上都属于设备文件,因为文件都是保存在磁盘中,对文件的操作,其本质上就是对磁盘操作)。
  4. 终端设备一般含有计算机的3大部件中的输入设备和输出设备(这与计算机发展历史相关,输入设备可以是键盘或其他能输出数据的设备,输出设备可以是显示器或其他能接收数据的设备)。
  5. 每个终端设备接入Linux系统,系统为该终端的输入功能绑定为0的文件描述符,输出功能绑定为1的文件描述符,在处理终端设备发送过来的指令出现错误时,错误提示绑定为2的文件描述符。

第3节 终端设备与文件描述符及重定向的默认行为

3.1 终端设备与文件描述符及重定向的默认行为

默认情况下:系统会帮用户默认补全输入及输出的重定向路径。所以一般情况下,手工写上重定向时,就是修改系统默认的输入与输出的路径。

比如:

cat jeson.sh # 等效 cat 0< jeson.sh 1> /dev/pts/0

处理方法输入设备负责为处理的方法提供数据源处理完的结果交给输出设备(由输出设备将数据输出)
用户输入catjeson.sh
系统自动补全cat0<jeson.sh1>/dev/pts/0

输入设备

可理解cpu获取数据入口

数据源设备发送设备

可理解cpu输出数据的出口

接收设备

磁盘上的所有类型文件,在概念上都属于设备文件,因为文件都是保存在磁盘中,对文件的操作,其本质上就是对磁盘操作。磁盘属于存储设备。

3.2 描述符与重定向;将数据重定向相应的设备中

pts/0  将echo输出的数据,定位到/dev/tty1 的输出设备

tty1  显示pts/0输入的数据

[jeson@mage-jump-01 ~/]# who
root tty1 2018-10-02 17:57
jeson pts/0 2018-10-02 20:12 (10.0.0.1)
[root@mage-jump-01 ~/]#ll /dev/fd/ # 查看自身的登录终端
总用量 0
lrwx------ 1 root root 64 10月 2 20:16 0 -> /dev/pts/0
lrwx------ 1 root root 64 10月 2 20:16 1 -> /dev/pts/0
lrwx------ 1 root root 64 10月 2 20:16 2 -> /dev/pts/0
lr-x------ 1 root root 64 10月 2 20:16 3 -> /proc/19301/fd
[root@mage-jump-01 ~/]# echo "how are you today?" >/dev/tty1
[jeson@mage-jump-01 ~/]# who
root tty1 2018-10-02 17:57
jeson pts/0 2018-10-02 20:12 (10.0.0.1)
[root@mage-jump-01 ~/]#ll /dev/fd/ # 查看自身的登录终端
total 0
lrwx------ 1 root root 64 Oct 2 20:21 0 -> /dev/tty1
l-wx------ 1 root root 64 Oct 2 20:21 1 -> /root/test.txt
lrwx------ 1 root root 64 Oct 2 20:21 2 -> /dev/tty1
lr-x------ 1 root root 64 Oct 2 20:21 3 -> /proc/19376/fd
[root@mage-jump-01 ~/]#how are you today?

pts/0和tty1 终端登录后的PID号

[jeson@mage-jump-01 ~/]$ps aux|egrep "[p]ts|tty"
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 18588 0.0 0.3 116624 3408 tty1 Ss+ 18:06 0:01 -bash
jeson 19491 0.0 0.2 156676 2328 ? S 20:32 0:00 sshd: jeson@pts/0
jeson 19492 0.0 0.3 116616 3232 pts/0 Ss 20:32 0:00 -bash
jeson 19648 0.0 0.1 155324 1864 pts/0 R+ 20:36 0:00 ps aux
jeson 19649 0.0 0.0 112720 992 pts/0 S+ 20:36 0:00 grep -E --color=auto [p]ts|tty

只要有PID号,/proc就会为其pid建立一个目录,该目录放该pid相关的数据文件

[jeson@mage-jump-01 ~/]$ls /proc/ | grep -E '[1-9]+' | column
1       17      19491   221     242     27      30      492     501     665
10      18      19492   222     243     270     342     493     502     7
11      18024   19636   224     263     271     365     494     503     743
1164    18588  19668   229     264     272     38      495     505     8
1166    18891   19669   231     265     273     40      496     57      88
13      19      19670   233     266     274     41      497     650     9
14      19398   2       236     267     28      42      498     651
15      19413   20      237     268     29      44      499     653
16      19489   21      239     269     3       476     5       658

3.3 终端设备接入系统,系统为终端设备设置对应文件描述符的操作方式(0,1,2)

系统为每一个接入终端都配备默认的文件描述符
[jeson@mage-jump-01 ~/]$ll /dev/std*
lrwxrwxrwx 1 root root 15 10月  1 18:38 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 10月  1 18:38 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 10月  1 18:38 /dev/stdout -> /proc/self/fd/1 
系统为pts/0接入终端默认绑定的文件描述符操作
[jeson@mage-jump-01 ~/]$ll /proc/self/fd
总用量 0
lrwx------ 1 jeson jeson 64 10月  2 21:12 0 -> /dev/pts/0  # stdin与pts/0远程终端关联
lrwx------ 1 jeson jeson 64 10月  2 21:12 1 -> /dev/pts/0  # stdout与pts/0远程终端关联
lrwx------ 1 jeson jeson 64 10月  2 21:12 2 -> /dev/pts/0 # stderr与pts/0远程终端关联
lr-x------ 1 jeson jeson 64 10月  2 21:12 3 -> /proc/19778/fd 
得出系统设备、特殊文件描述符、终端的链接关系为
/dev/stderr   ->  /proc/self/fd/2  -> /dev/pts/0
/dev/stdin    ->  /proc/self/fd/0  -> /dev/pts/0
/dev/stdout   ->  /proc/self/fd/1  -> /dev/pts/0 

3.4 打开文件描述符

  1. 打开文件描述符有程序自动指定和人为手动指定编号两种方式
  2. 程序在打开文件描述符的时候,有三种可能的行为:从描述符中读、向描述符中写、可读也可写。
  3. 从lsof的FD列可以看出程序打开这个文件是为了从中读数据,还是向其中写数据,亦或是既读又写。

例如:以下实例就是打开文件从中读、写、读写数据的(3r的r是read,w是write,u是read and write)。

窗口1

窗口2

程序自动指定编号人为手动指定编号
只读模式;命令行执行如下命令
[jeson@mage-jump-01 ~/]$lsof -n | grep 'read.txt'|column -t
  tail  2135  jeson  3r  REG  8,2  0  41054766  /home/jeson/read.txt 
tail -f read.txtexec 3<read.txt
只写模式;命令行执行如下命令
[jeson@mage-jump-01 ~/]$lsof -n | grep 'write.txt'|column -t
  cat  2099  jeson  1w或3w  REG  8,2  0  41054756  /home/jeson/write.txt 
cat > write.txtexec 3>read.txt
可读可写模式;命令行执行如下命令
[jeson@mage-jump-01 ~/]$lsof -n | grep 'read_write.txt'|column -t
  vim  2197  jeson  4u  REG  8,2  12288  41054769  /home/jeson/.read_write.txt.sap
vim read_write.txtexec 4<>read.txt

3.5 复制、关闭文件描述符

文件描述符的复制(duplicate),文件描述符的复制表示当前操作的文件描述符被(作用或者理解为移动)到另一个文件描述符中。

[n]>&digit- :将文件描述符digit代表的输出文件移动到n上,并关闭digit值的描述符。

[n]<&digit- :将文件描述符digit代表的输入文件移动到n上,并关闭digit值的描述符。

[n]<&- :直接关闭n描述符。

实例 1:

[jeson@mage-jump-01 ~/]$lsof -n | grep "read.txt" | column -t
bash    19492  jeson  3r  REG  8,2  0  41054753  /home/jeson/read.txt
[jeson@mage-jump-01 ~/]$exec 4<&3- 
[jeson@mage-jump-01 ~/]$lsof -n | grep "read.txt" | column -t
bash    19492  jeson  4r  REG  8,2  0  41054753  /home/jeson/read.txt 
[jeson@mage-jump-01 ~/]$exec 4<&-
[jeson@mage-jump-01 ~/]$lsof -n | grep "read.txt" | column -t
[jeson@mage-jump-01 ~/]$

可见:fd=3移动到fd=4后,原本与fd=3关联的read.txt已经关闭,并且关联到fd=4上; 最后把fd=4直接关掉了。

实例 2:

[jeson@mage-jump-01 ~/]$echo "I am a boy"
I am a boy
[jeson@mage-jump-01 ~/]$echo "I am a boy" >/dev/null 2>&1
[jeson@mage-jump-01 ~/]$ 

画图说明:

终端设备 tty,pty,pts 概念与文件描述符的联系第3张

第4节 文件描述符的高阶使用

案例 1 :

[jeson@mage-jump-01 ~/]$echo "123456" >jeson.sh
[jeson@mage-jump-01 ~/]$exec 5<>jeson.sh 
[jeson@mage-jump-01 ~/]$read -n 3 <&5
[jeson@mage-jump-01 ~/]$echo $REPLY
    123
[jeson@mage-jump-01 ~/]$echo -n "+" >&5
[jeson@mage-jump-01 ~/]$exec 3>&-
[jeson@mage-jump-01 ~/]$cat jeson.sh 
    123+56 

简要描述:

打开文件 jeson.sh 以read/write方式,并分配fd=5给该文件进程。
这时fd=0已经绑定到fd=5上,而fd=5的重定向目标为jeson.sh,所以fd=0的目标也是jeson.sh,即从jeson.sh中读取数据。这里read命令读取3个字符,由于read命令中没有指定变量,因此分配给默认变量REPLY。注意,这个命令执行结束后,fd=0的重定向目标会变回/dev/stdin。
这时fd=1也已经绑定到fd=5上,而fd=5的重定向目标文件为jeson.sh,所以fd=1的目标也是jeson.sh文件,即数据写入到jeson.sh中。这里写入一个+号。注意,这个命令结束后,fd=1的重定向目标回变回/dev/stdout。
关闭fd=5,这也会关闭其指向的文件jeson.sh,关闭文件操作进程。

案例 2 :

[jeson@mage-jump-01 ~/]$exec 6>&1
[jeson@mage-jump-01 ~/]$exec > jeson.sh
[jeson@mage-jump-01 ~/]$echo "I am a boy"
[jeson@mage-jump-01 ~/]$exec 1>&6-
[jeson@mage-jump-01 ~/]$cat jeson.sh 
  I am a boy

简要描述:

  1. 打开文件描述符进程fd=6,并指向1对应的/dev/stdout。
  2. 打开文件描述符fd=1进程指向jeson.sh文件。
  3. 输入的数据,定位到描述符fd=1进程,1进程对应jeson.sh文件。

免责声明:文章转载自《终端设备 tty,pty,pts 概念与文件描述符的联系》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Nginx https加密以及nginx日志配置与管理Net跨域请求设置下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

CentOs如何挂载硬盘(手把手教你 )

一、重新以读写方式挂载硬盘: mount -o remount, rw / 二、远程SSH登录上Centos服务器后,进行如下操作 提醒:挂载操作会清空数据,请确认挂载盘无数据或者未使用 第一步:列出所有磁盘   命令: ll /dev/disk/by-path 提示:如果无法确认数据盘设备名称,请使用df命令来确认系统盘的名称,从而排除挂错盘的情...

gitlab介绍与操作

Gitlab GitLab 是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面进行访问公开的或者私人项目。 与 Github 类似,GitLab 能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访 问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序(W...

[转]iSCSI for FreeBSD

Suppose you want to use a remote iSCSI device, but you don't exactly trust either the storage or the network in between. Of course, there's a way around it :) The setup presente...

shell重定向符

shell重定向符   >, < 及>>,<< 文件描述符    0, 标准输入     对应文件/dev/stdin 1,标准输出     对应文件/dev/stdout 2,错误输出     对应文件/dev/stderr &1,标准输出通道 &2,标准输入通道 command > file 是...

nodejs中文件,目录的操作(1)

  首先,我们对fs文件系统分为两类操作,第一类是xxx方法,第二类是xxxSync方法。所有的fs操作几乎都是这两类,第一类是异步回调,第二类是同步等待。   A.对于文件的读写操作     a.完整性读写       1.fs.readFile(filename,[options],callback)//可以用来完整读取一个整的文件。       2....

TI AM335X 网卡驱动解析

1.CPSW驱动及设备的初始化; (1)首先驱动注册cpsw_driver ,会自动进入cpsw_probe执行; 1 static struct platform_driver cpsw_driver = { 2 .driver = { 3 .name = "cpsw", 4 .owner = T...