简单理解linux文件描述符

简单理解linux文件描述符

文件描述符

文件描述符可以简单理解为一个不透明的句柄(我自己理解的),当我们创建文件或者打开已有文件的时候,内核就会向进程返回文件描述符,它可以简单理解为是操作系统为为文件创建的索引。

linux系统中,每个进程都有3个默认的文件描述符,分别用012来表示,含义分别如下:

0:标准输入,对应的设备文件为/dev/stdin

1:标准输出,对应的设备文件为/dev/stdout

2:错误输出,对应的设备文件为/dev/stderr

除了默认文件描述符以外,还能为进程创建其他文件描述符,甚至是tcp套接字。

linux中,可以查看/proc/进程号/fd/下的文件来查看该进程创建的文件描述符。

比如在终端中使用vim打开了一个新的文件123。除了012等默认文件描述符外,还有其他的描述符,比如:

bash 复制代码
3 -> /root/.123.swp

如果在终端中打开了一个套接字,比如telnet,那么也会有相应的文件描述符中,比如:

bash 复制代码
4 -> socket:[179916]

这个套接字指向的是一个inode号,可以使用lsof等工具查询。

如果你还是不理解文件描述符,那么请看下面这个例子:

linux中,使用exec可以创建文件描述符,比如:

bash 复制代码
exec 3<>/root/123.txt

上述命令创建了一个文件描述符为3的句柄,这个句斌属于操作系统,可以为外部程序锁调用,可以使用查看/dev/fd/目录下查看该信息,比如:

bash 复制代码
0 -> /dev/pts/1
1 -> /dev/pts/1
2 -> /dev/pts/1
3 -> /root/123.txt

可以直接向/dev/fd/3写入数据的方式来存储数据,比如;

bash 复制代码
echo 123456 > /dev/fd/3

上述将123456这个字符串以重新向的方式写入/dev/fd/3文件中。

再看实际的文件,该文件中已经有了该字符串。

bash 复制代码
# cat /root/123.txt
123456
#

使用完成后,记得关闭该文件描述符。

bash 复制代码
exec 3>&-

标准输出和错误输出

上述有了文件描述符的铺垫,使用重定向就比较简单了。

bash中,标准输出使用>关键字,比如:

bash 复制代码
ls -l > filename

上述命令将ls -l的标准输出写入到文件filename中(linux一切皆文件)

而错误输出的关键字是2>关键字, 比如:

bash 复制代码
abcd 2> filename

假设不存在abcd这个命令,则使用该操作就会将错误输出重定向到filename中。

上述的>2>关键字使用的时候都会将文件原始数据给清理掉。

除此之外,还有追加标准输出、追加错误输出,则分别使用>>2>>关键字来表示,例如:

bash 复制代码
ls -l >> filename

上述命令将ls -l的标准输出追加到文件filename中,不会清理掉原文件的内容。

而错误追加输出也是一样的:

bash 复制代码
abcd 2>> filename

bash中,标准输出和错误输出可以执行同一个文件,比如,下面这条语句:

bash 复制代码
comamnd > filename 2> &1

它表示将 command 的标准输出结果都重定向到文件 filename中,然后将标准错误重定向到与标准输出相同的位置,即 filename文件。这里需要注意的是,2>&1 中间不能有空格,其中 2> 表示标准错误输出,&1 指的是刚刚设置的标准输出文件描述符。

bash中,使用&>可以实现上述功能,你可以将其理解为语法糖:

bash 复制代码
comamnd &> filename

总结

简单介绍了一下文件描述符,这是一个非常有意思的事情,将其理解为一个不透明的句柄就可以了。linux操作系统为每一个进程都创建了3个文件描述符,分别是标准输入:0、标准输出1和错误输出2。如果程序后期打开了新的文件,则会在进程描述符下创建新的fd文件,比如:/proc/进程Id/fd下,linux下一切皆文件,甚至是tcp句柄,比如:

bash 复制代码
exec 3<>/dev/tcp/127.0.0.1/80

这个命令表示创建了一个读写的文件描述符,id3,指向/dev/tcp/127.0.0.1/80这个文件,这个文件表示建立一个127.0.0.1:80tcp连接。

bash 复制代码
echo -e "GET / HTTP/1.1\r\n\r\n" >&3

向这个文件描述符写入简单的http请求报文。

bash 复制代码
cat <&3

读取文件描述符所对应的文件内容,即服务器返回的响应报文。

后面简单介绍了一下标准输出和错误输出,如果理解了文件描述符,那么理解标准输出和错误输出就不成问题了。

相关推荐
花落已飘2 天前
STM32中实现shell控制台(命令解析实现)
stm32·shell
Johny_Zhao2 天前
Docker 一键安装部署 JumpServer 堡垒机
linux·网络安全·信息安全·云计算·shell·jumpserver·ldap·yum源·系统运维
Johny_Zhao3 天前
Ubuntu系统安装部署Pandawiki智能知识库
linux·mysql·网络安全·信息安全·云计算·shell·yum源·系统运维·itsm·pandawiki
bcbobo21cn4 天前
初步了解Linux etc/profile文件
linux·运维·服务器·shell·profile
1.01^100016 天前
[2-02-02].第59节:功能函数 - 函数基础
shell
___波子 Pro Max.17 天前
Shell脚本中&&和||语法解析
shell
lewis_lk19 天前
文本处理三剑客: grep、sed、awk使用指南
后端·shell
Johny_Zhao20 天前
企业级LDAP-RADIUS深度集成高可用方案
linux·网络·python·网络安全·信息安全·云计算·shell·cisco·系统运维
Johny_Zhao21 天前
基于CentOS Stream 8的物联网平台深度优化方案
linux·网络·网络安全·信息安全·云计算·shell·yum源·系统运维
Johny_Zhao22 天前
CentOS Stream 8 高可用 Kuboard 部署方案
linux·网络·python·网络安全·docker·信息安全·kubernetes·云计算·shell·yum源·系统运维·kuboard