简单理解linux文件描述符

简单理解linux文件描述符

文件描述符

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

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

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

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

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

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

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

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

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

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

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

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

bash 复制代码
cat <&3

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

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

相关推荐
fox_charon1 天前
Windows 下 CLI 参数的引号陷阱:为什么 --resume 'uuid' 会失败
windows·shell·cmd·cli·引号
吴声子夜歌10 天前
Shell编程实例——编写安全的shell脚本(二)
linux·运维·shell
吴声子夜歌11 天前
Shell编程实例——内务及管理任务(一)
linux·运维·shell
吴声子夜歌11 天前
Shell编程实例——高级脚本编程(一)
linux·运维·网络·shell
吴声子夜歌11 天前
Shell编程实例——bash的配置与自定义(二)
linux·运维·shell
吴声子夜歌12 天前
Shell编程实例——与解析相关的任务(二)
linux·运维·shell
吴声子夜歌12 天前
Shell编程实例——脚本编程的附加特性
linux·运维·shell
云计算练习生12 天前
什么是内核?操作系统内核到底管哪些事
linux·windows·操作系统·内核·shell
吴声子夜歌15 天前
Shell编程实例——bash入门
linux·运维·shell
Swizard16 天前
Linux 日志神器 journalctl 完全指南:彻底替代传统日志查看方式
shell