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

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

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

相关推荐
zfj32120 小时前
sshd除了远程shell外还有哪些功能
linux·ssh·sftp·shell
刘某的Cloud2 天前
shell脚本-read-输入
linux·运维·bash·shell·read
柏木乃一3 天前
进程(2)进程概念与基本操作
linux·服务器·开发语言·性能优化·shell·进程
pr_note3 天前
Vim 常用快捷键速查
shell·tcl
童话ing3 天前
【Shell】自动替换指定项目tag并提merge request
shell
岚天start4 天前
[K8S监控]-K8S容器pod异常状态监控脚本并推送钉钉告警
容器·kubernetes·钉钉·shell·告警
AlbertS7 天前
Shell脚本中set -e和set -o pipefail的作用
shell·pipefail·trap·脚本错误·控制流程
阿海5748 天前
安装php7.4.33的shell脚本
php·shell
阿海5748 天前
卸载redis7.2.4的shell脚本
linux·redis·shell
小嘟嘟139 天前
从基础到进阶:掌握 userdel,玩转 Linux 用户管理的 “减法” 艺术
linux·运维·网络·shell