简单理解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

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

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

相关推荐
dingdingfish9 小时前
Bash 学习 - 第1章:Introduction
bash·shell·programming·introduction
pr_note2 天前
legality检查
shell·tcl
啥都不懂的小小白3 天前
Shell脚本编程入门:从零基础到实战掌握
前端·shell
dingdingfish7 天前
GNU Parallel 学习 - 第1章:How to read this book
bash·shell·gnu·parallel
似霰10 天前
Linux Shell 脚本编程——核心基础语法
linux·shell
似霰10 天前
Linux Shell 脚本编程——脚本自动化基础
linux·自动化·shell
偷学技术的梁胖胖yo11 天前
Shell脚本中连接数据库查询数据报错 “No such file or directory“以及函数传参数组
linux·mysql·shell
纵有疾風起20 天前
【Linux 系统开发】基础开发工具详解:软件包管理器、编辑器。编译器开发实战
linux·服务器·开发语言·经验分享·bash·shell
gis分享者22 天前
Shell 脚本中如何使用 here document 实现多行文本输入? (中等)
shell·脚本·document·多行·文本输入·here
柏木乃一22 天前
基础IO(上)
linux·服务器·c语言·c++·shell