exec与文件描述符

在*nux系统中,一般在操作文件时会直接使用文件名,在支持POSIX的各种环境中,提供了一系列用于操作文件的工具,短小精悍却又强大得变态。在shell环境下,还经常文件描述符(正整数)来操作文件。
系统默认打开的描述符有3个:
    0   - 标准输入
    1   - 标准输出
    2   - 标准出错
所以,只要够斯文(别整太大的数,它不仅难记,而且你不需要),几乎所有的正整数都可以绑定到某个文件。

1、通过exec分配文件描述符
#!/bin/sh

exec 3<>hello.txt           # 以读写方式绑定到文件描述符"3"
echo "hello exec" >&3       # 写入"hello exec",如果之前有内容,这里将会从文件开头进行覆盖
echo "hello world" >&3      # 写入"hello world“,新的一行!
exec 3>&-                   # 关闭写,禁止写,然而,实际上它也不能读了~
                            # 如果是exec 3<&-,关闭读,同时它也不能写了~

在上面的示例中,将文件hello.txt绑定到了描述符3,如果要将输出重定向到hello.txt,只需要略作修改

2、将标准输出重定向到hello.txt
#!/bin/sh

exec 1>hello.txt        # 将输出重定向到文件hello.txt,从此以后,这个脚本中的输出都将被写入文件hello.txt
echo "hello exec"
echo "hello world"
就这么简单,在终端再也见不着输出了,因为你已经明确地告诉他,把这些信息写到文件去……

3、在上面这个示例中,输出被重定向了,如果要恢复怎么办?
#!/bin/sh

exec 100>&1             # 将文件描述符100连接到标准输出
                        # 由于之后还要输出到终端,所以我们不得不使用一个临时的描述符来保存它!
exec 1>hello.txt        # 将输出重定向到文件hello.txt,从此以后,这个脚本中的输出都将被写入文件hello.txt
echo "hello exec"
echo "hello world"
exec 1>&100 100>&-      # 将标准输出连接到100,这是之前保存的标准输出
                        # 将描述符100关了,一了百了,因为已经还原标准输出了,留着它实在没必要

echo "oh, my god!"      # 从这句开始将显示在终端上

4、标准输入的操作与2、3相似,只是使用的是"<"
#!/bin/sh

exec 100<&0
exec <hello.txt
read line1
echo $line1
read line2
echo $line2

exec 0<&100 100>&-

read custom

<think>嗯,用户问的是关于“文件delete文件描述符查看”的内容。首先,我需要理解用户的具体需求。可能他们是在操作系统中遇到了文件描述符的问题,或者在编程时遇到了相关错误,比如试图访问已关闭的文件描述符。用户可能想了解如何查看已被删除的文件描述符,或者如何确认某个文件描述符是否已经被正确关闭和删除。 首先,我需要回顾一下文件描述符的基本概念。在Unix/Linux系统中,文件描述符是一个非负整数,用于标识打开的文件或I/O资源。当进程打开文件、套接字等时,系统会分配一个文件描述符。当文件被关闭时,描述符会被释放。但有时候,即使文件被删除(例如使用unlink),如果仍有进程持有该文件的描述符,文件的数据可能仍然存在于磁盘上,直到所有描述符都关闭。 接下来,“delete文件描述符”可能指的是关闭文件描述符,即调用close()函数。用户可能想知道如何检查哪些文件描述符已经被关闭,或者如何查看进程当前打开的文件描述符。 常用的工具包括lsof和查看/proc文件系统。例如,使用lsof -p <PID>可以查看指定进程打开的所有文件描述符。而/proc/<PID>/fd目录下包含了该进程所有打开的文件描述符的符号链接。用户可以在这里查看哪些描述符仍然存在,进而判断是否已被关闭。 另外,用户可能混淆了“删除文件”和“关闭文件描述符”。删除文件(unlink)只是移除文件名到inode的链接,而文件数据是否被清除取决于是否有进程仍持有该文件的描述符。这部分可能需要解释清楚。 还有可能用户遇到了文件描述符泄漏的问题,即进程未正确关闭不再使用的描述符,导致资源耗尽。这时候需要检查进程的打开文件情况,找出未关闭的描述符。 总结用户的需求,可能需要分步骤说明如何查看进程的文件描述符状态,如何确认是否已关闭,以及相关工具的使用方法。同时需要区分文件删除和描述符关闭的不同影响,确保用户理解两者之间的关系。</think>在Linux系统中,文件描述符(file descriptor)是进程访问文件或其他I/O资源的抽象句柄。关于"查看已关闭/删除的文件描述符"的完整说明如下: 1. **基本概念** - 文件描述符是0~n的整数,每个进程独立维护 - 打开文件时会分配新描述符,关闭文件时描述符被回收 - 已关闭的描述符会被系统立即回收,无法直接查看 2. **查看当前打开的描述符** 使用以下方法查看进程当前持有的文件描述符: ```bash # 查看所有打开的文件描述符 ls -l /proc/<PID>/fd # 使用lsof命令 lsof -p <PID> # 查看限制值 cat /proc/sys/fs/file-nr ``` 3. **已关闭描述符的特殊说明** - 关闭后的描述符会立即被系统回收,无法再访问 - 如果尝试操作已关闭的fd,会得到"Bad file descriptor"错误 - 通过strace可以跟踪close()系统调用: ```bash strace -e trace=close -p <PID> ``` 4. **常见问题排查** 当出现文件描述符泄漏时: ```bash # 查看进程当前打开的文件数 ls /proc/<PID>/fd | wc -l # 按类型统计 lsof -p <PID> | awk '{print $5}' | sort | uniq -c # 查看最大允许值 cat /proc/<PID>/limits | grep 'Max open files' ``` 5. **注意事项** - 文件描述符关闭后立即失效,无法恢复使用 - 重复关闭同一描述符会导致错误 - 父进程fork出的子进程会继承文件描述符表 - 使用close-on-exec标志可避免描述符泄漏到子进程 示例调试流程: ```bash # 1. 查找进程PID ps aux | grep <process-name> # 2. 查看实时文件描述符 watch -n 1 "ls -l /proc/$(pidof <process>)/fd" # 3. 分析打开的文件类型 lsof -p $(pidof <process>) +fg ``` 掌握这些工具和方法,可以有效地诊断文件描述符相关的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值