终端设备与文件描述符及重定向

相关好文章推荐

https://blog.csdn.net/yazhouren/article/details/78793367

 

欲知文件描述符,必先知终端及重定向


 终端设备(tty,pts,pty) 

 

 


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

Linux中一切皆文件,有文件就必有路径,有路径就必有如何来,如何回的指向。因此文件描述符与重定向为此而生。(成语:礼尚往来)

所有的存在都以文件的形式示现,而文件描述符专用于系统调用文件时使用,为打开的文件打上标识(通俗的讲就是上班穿工作服,回家后脱工作服)。

终端设备文件描述符重定向[ >,< ](注意不是追加重定向)不是单独存在,而是相辅相成。

重定向主要的作用数据源流向到相应的设备中磁盘上的所有类型文件,在概念上都属于设备文件,因为文件都是保存在磁盘中,对文件的操作,其本质上就是对磁盘操作。)

终端设备一般含有计算机的五大部件中的输入设备和输出设备(这与计算机发展历史相关,输入设备可以是键盘或其他能输入数据的设备,输出设备可以是显示器或其他能接收数据的设备)

每个终端设备接入Linux系统,系统为该终端的输入功能绑定为0的文件描述符,输出功能绑定为1的文件描述符,在处理终端设备发送过来的指令出现错误时,错误提示绑定为2的文件描述符。

终端设备文件描述符文件描述符对应的文件重定向(箭头所指就是流动的方向数据的流向打开文件即产生该文件的文件描述符
输入功能0/dev/stdin

>(输出)

数据源 (输出)>设备

ls >a.txt3 ~ 65535
输出功能1/dev/stdout

<(输入)

命令 < (输入)数据源

cat <a.txt
 2/dev/stderr   

 


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

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

对所爱,要重复大声说:trust me , I love you

Linux中一切皆文件,有文件就必有路径,有路径就必有如何来,如何回的指向。因此文件描述符与重定向为此而生。(成语:礼尚往来)

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

比如:[root@server01 ~]# cat a.txt  # 等效  cat 0<a.txt 1>/dev/pts/0

 处理方法 

输入设备(0)负责为处理的方法提供数据源(数据源在磁盘设备上的a.txt里面)

要加工的数据在哪里来

处理完的结果由输出设备(1)将数据送给下一个设备接收

加工完的数据往哪里去

用户输入cat  a.txt   
系统自动补全cat0<a.txt1>/dev/pts/0
  

输入设备

可理解cpu获取数据入口

 数据源设备

发送设备

可理解cpu输出数据的出口

 接收设备

 概念图

 

语法格式:命令(不同的命令对接收数据源有所不同)   [ 输入设备文件描述符 重定向(<) 数据源设备] [ 输出设备的文件标识符  重定向(>)  接收设备文件(或文件名)&文件描述符 ]

比如:[root@server01 ~]# ls 1>a.txt 2>/dev/null #等效 ls >a.txt 2>/dev/null

服务端
ls1>a.txt2>/dev/null
命令产生数据源系统的输出设备的文件描述符重定向接收设备系统的错误输出设备的文件描述符 接收设备

 

比如:[root@server01 ~]# ls 

服务端
 处理方式系统接收数据入口 <提供数据源的设备系统返回数据出口 接收的设备
用户输入ls      
系统自动补全lsls命令根据参数而处理,而不是对数据源处理

1>/dev/pts/0

 

比如:[root@server01 ~]# cat 0<a.txt  #等效 cat <a.txt

 
 命令处理方式系统接收数据入口流入提供数据源的设备结果出口流入终端设备错误出口流入终端设备
用户输入cat  a.txt      
系统自动补全cat0<a.txt1>/dev/pts/02>&1

 

图解修改系统为命令行自动补全的路径

 

终端的请求与服务端的响应
 常规的书写格式 自动补全结果返回路径
[root@server01 ~]# ls
anaconda-ks.cfg  a.txt  install.log  install.log.syslog
[root@server01 ~]#
[root@server01 ~]# ls 1>/dev/pts/0 2>/dev/pts/0
anaconda-ks.cfg  a.txt  install.log  install.log.syslog
[root@server01 ~]# 
 

1 终端(输入设备)提交命令到服务端

2 ls产生了数据源

3 结果服务器的输出设备 > 终端

 

文件描述符与重定向的默认等价关系(修改默认重定向及文件描述符的变化流程如下图

ls 1>a.txt 2>a.txt

等价

ls >a.txt 2>a.txt # >a.txt 默认等价 1>a.txt

等价

ls >a.txt 2>&1 # 2>&1 其中&1表示/dev/stdout,2指向1了。

等价

ls &>a.txt #  

 

 

文件描述符参与系统的/dev/stdin,/dev/stdout,/dev/stderr设备与每个终端设备的绑定关系

 文件描述符(0,1,2)成为系统的输入设备,输出设备,错误输出设备与终端设备的纽带,命门就在此处。

终端登录系统,系统的输入,输出,错误设备与终端设备进行绑定
pts/0pts/1
[root@server01 ~]# ll /dev/std*
lrwxrwxrwx 1 root root 15 Sep 29  2018 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Sep 29  2018 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Sep 29  2018 /dev/stdout -> /proc/self/fd/1
[root@server01 ~]# ll /proc/self/fd
total 0
lrwx------ 1 root root 64 Sep 29 18:15 0 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 29 18:15 1 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 29 18:15 2 -> /dev/pts/0
lr-x------ 1 root root 64 Sep 29 18:15 3 -> /proc/26143/fd
[root@server01 ~]# 
[root@server01 ~]# ll /dev/std*
lrwxrwxrwx 1 root root 15 Sep 29  2018 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Sep 29  2018 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Sep 29  2018 /dev/stdout -> /proc/self/fd/1
[root@server01 ~]# ll /proc/self/fd/
total 0
lrwx------ 1 root root 64 Sep 29 18:15 0 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 29 18:15 1 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 29 18:15 2 -> /dev/pts/1
lr-x------ 1 root root 64 Sep 29 18:15 3 -> /proc/26145/fd
[root@server01 ~]# 

 

改变默认的输出设备(手机充值按错号码了)
pts/0 终端设备pts/1 终端设备
[root@server01 ~]# ls
anaconda-ks.cfg  a.txt  install.log  install.log.syslog
[root@server01 ~]# 
[root@server01 ~]# who
root     pts/0        2018-09-29 12:02 (192.168.6.1)
root     pts/1        2018-09-29 14:34 (192.168.6.1)
[root@server01 ~]# ll /dev/fd/
total 0
lrwx------ 1 root root 64 Sep 29 15:42 0 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 29 15:42 1 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 29 15:42 2 -> /dev/pts/0
lr-x------ 1 root root 64 Sep 29 15:42 3 -> /proc/25919/fd
[root@server01 ~]# ls 1>/dev/pts/1 2>/dev/pts/1
[root@server01 ~]# echo "pts/1,我的显示在你那边吗?" 1>/dev/pts/1 
[root@server01 ~]# 若是手机充值给我就好了
[root@server01 ~]# who
root     pts/0        2018-09-29 12:02 (192.168.6.1)
root     pts/1        2018-09-29 14:34 (192.168.6.1)
[root@server01 ~]# ll /dev/fd/
total 0
lrwx------ 1 root root 64 Sep 29 16:30 0 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 29 16:30 1 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 29 16:30 2 -> /dev/pts/1
lr-x------ 1 root root 64 Sep 29 16:30 3 -> /proc/25968/fd
[root@server01 ~]# anaconda-ks.cfg  a.txt  install.log  install.log.syslog
pts/1,我的显示在你那边吗?

[root@server01 ~]# echo "若是手机充值给我就好了" >/dev/pts/0
 

  

查看文件的描述(file description,fd)

一旦打开文件,系统就会自动产生对该文件的文件描述符,表示在内存地址指向该文件资源(可以理解文件描述符类似变量名)

pts/0pts/1
[root@server01 ~]# tail -f a.txt 
123

[root@server01 ~]# lsof -n | grep 'a.txt' |column -t
tail  26107  root  3r  REG  8,3  4  133213  /root/a.txt
[root@server01 ~]#
 

3 :表示tail 打开a.txt的文件所产生的文件描述符,3与a.txt就形成关联

r:tail以读的方式访问a.txt

w:可写

u:可写可读

 


 

文件描述符与文件操作进程的关系

 

& 的快速理解

[root@server01 ~]# echo "I am a" >a.txt 
[root@server01 ~]# 
[root@server01 ~]# a='hi'
[root@server01 ~]# echo $a
hi
[root@server01 ~]# cat >&1 <a.txt # 文件描述符1,被系统默认绑定/dev/stdout,即&1就是指向 /dev/stdout 
I am a
[root@server01 ~]#

 

 常用方式

[root@server01 ~]# cat a.txt 
here is a
[root@server01 ~]# >b.txt 
[root@server01 ~]# ls
anaconda-ks.cfg  a.txt  b.txt  install.log  install.log.syslog
[root@server01 ~]# ls c.txt >a.txt 2>b.txt #正确的结果放入a.txt,错误结果放入b.txt
[root@server01 ~]# cat a.txt #为什么a.txt没有数据,没有结果,文件描述符1默认输出为空。
[root@server01 ~]# cat b.txt 
ls: cannot access c.txt: No such file or directory
[root@server01 ~]# 
 常用方式
[root@server01 ~]# >a.txt
[root@server01 ~]# echo "here is b">b.txt 
[root@server01 ~]# ls a.txt >a.txt 2>b.txt  
[root@server01 ~]# cat a.txt 
a.txt
[root@server01 ~]# cat b.txt #为什么b.txt没有了,道理同上
[root@server01 ~]# 
& 的作用
[root@server01 ~]# ls >&1  #&在重定向后面(必须是数字),其作用就是对文件描述符对应的文件(设备文件)操作方式
anaconda-ks.cfg  a.txt  install.log  install.log.syslog
[root@server01 ~]# 
& 的文件操作-只读
[root@server01 ~]# exec 5<a.txt #打开文件描述符为5的a.txt文件操作进程,操作模式只读。
[root@server01 ~]# cat <&5 # 等价 cat a.txt。
anaconda-ks.cfg
a.txt
install.log
install.log.syslog
[root@server01 ~]# lsof -n |grep 'a.txt'|column -t
bash 26312 root 5r REG 8,3 53 133213 /root/a.txt
grep 26378 root 5r REG 8,3 53 133213 /root/a.txt
column 26379 root 5r REG 8,3 53 133213 /root/a.txt
[root@server01 ~]#
[root@server01 ~]# exec 5<&- # 5<&- 表示关闭文件描述为5的文件操作进程
 & 的文件操作-只写
[root@server01 ~]# exec 5>a.txt #打开文件描述符为5的a.txt文件操作进程,操作模式为只写。
[root@server01 ~]# cat <&5
cat: -: Bad file descriptor
[root@server01 ~]# echo 'haha' >>&5
-bash: syntax error near unexpected token `&'
[root@server01 ~]# echo 'haha' >&5
[root@server01 ~]# cat a.txt 
haha
[root@server01 ~]# exec 5>&- #5>&- 关闭文件描述符为5的文件操作进程
[root@server01 ~]# 
 & 的文件操作-读写
[root@s01 ~]# cat a.txt 
anaconda-ks.cfg
a.txt
install.log
install.log.syslog
ddr
[root@s01 ~]# exec 5<>a.txt #打开文件描述符为5的a.txt文件操作进程,操作模式可读可写。
[root@s01 ~]# read -n 5 <&5 #从文件的第一个位置开始读取5个字节,并游标到第5个位置
[root@s01 ~]# echo xxx >&5 #在游标第5个位置插入 xxx 及 换行符
[root@s01 ~]# cat <&5 #从在当下游标的位置显示到文件尾
ks.cfg
a.txt
install.log
install.log.syslog
ddr
[root@s01 ~]# exec 5<&- 
[root@s01 ~]# exec 5>&- [root@s01 ~]# cat a.txt anacoxxx #这个就是修改的地方了。从第5个字符开始替换,替换了3个字符1个换行符共4个字符 ks.cfg a.txt install.log install.log.syslog ddr [root@s01 ~]#

转载于:https://www.cnblogs.com/BoNuo/articles/9721527.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值