如果你创建了新的输入或输出文件描述符,shell会在脚本退出时自动关闭它们。然而在有些情况下,你需要在脚本结束前手动关闭文件描述符。
要关闭文件描述符,将它重定向到特殊符号&-
举例如下:
[root@localhost shell]# cat test.sh
#!/bin/bash
exec 3>access.log
echo "This is a test msg" >&3
exec 3>&-
echo "This won't work" >&3
[root@localhost shell]# ./test.sh
./test.sh:行6: 3: 错误的文件描述符
[root@localhost shell]# cat access.log
This is a test msg
一旦关闭了文件描述符,就不能在脚本中向它写入任何数据,否则shell会生成错误消息。
不写数据的情况下,如果随后在脚本中打开同一个输出文件,shell会用一个新文件替换已有文件。
[root@localhost shell]# ls
test.sh
[root@localhost shell]# cat test.sh
#!/bin/bash
exec 3>access.log
echo "This is a test msg" >&3
exec 3>&-
cat access.log
exec 3>access.log
echo "This'll be bad" >&3
[root@localhost shell]# ./test.sh
This is a test msg
[root@localhost shell]# cat access.log
This'll be bad
除非使用追加模式(>>
)
[root@localhost shell]# cat test.sh
#!/bin/bash
exec 3>access.log
echo "This is a test msg" >&3
exec 3>&-
cat access.log
exec 3>>access.log
echo "This'll be bad" >&3
[root@localhost shell]# ./test.sh
This is a test msg
[root@localhost shell]# cat access.log
This is a test msg
This'll be bad
附录:
lsof 命令会列出整个Linux系统打开的所有文件描述符。这是个有争议的功能,因为它会向非系统管理员用户提供Linux系统的信息。鉴于此,许多Linux系统隐藏了该命令。
最常用参数(-p,-d)
前者允许指定进程ID(PID),后者允许指定要显示的文件描述编号
要想知道进程的当前PID,可以用特殊环境变量$$
(shell会将它设为当前PID)。-a选项执行布尔AND运算。
关于TYPE指文件类型
CHR代表字符型,BLK代表块型,DIR代表目录,REG代表常规文件