说明:
linux系统中为了方便内核管理系统打开的文件,会在/proc 目录生成索引文件,这个索引文件就是与打开的每个文件相对应的文件描述符(FileDescription);
- 举例 :
[root@node2 proc]# systemctl start nginx
[root@node2 proc]# ps -ef|grep nginx
root 16442 1 0 21:37 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 16443 16442 0 21:37 ? 00:00:00 nginx: worker process
那么在/proc 目录下会生成16442和16443 的目录 fd,他们就是文件描述符的信息:
[root@node2 fd]# pwd
/proc/16442/fd
内核直接基于文件描述符就可以管理文件了,例如我们现在把5 这个文件描述符对应的access.log 文件移走:
可以看到5现在对应的文件是移动后的/tmp/access.log ,即文件描述符可以直接链接目标文件,不管目标文件怎么改,文件描述符都不会变动。
而对于linux系统它有3个默认的文件描述符,即0,1,2
0:STDIN_FILENO 表示标准输入
1 :STDOUT_FILENO 表示标准输出
2:STDERR_FILENO 表示标准错误输出
默认打开一个新文件,它的文件描述符为3。
2>&1 的含义
举例 ,执行一个命令时有报错:
[root@node2 sh]# ls -ltr aaa
ls: 无法访问aaa: 没有那个文件或目录
[root@node2 sh]# ls -ltr aaa >aa.log 2>&1
[root@node2 sh]# cat aa.log
ls: 无法访问aaa: 没有那个文件或目录
[root@node2 sh]#
- 2 表示标准错误输出,&1 表示1文件描述符,即标准输出,> 表示重定向
那么,2>&1 表示将标准错误输出重定向到标准输出; - ls -ltr aaa >aa.log 2>&1 的含义
ls -ltr aaa >aa.log 表示将 “ls -ltr aaa” 这条命令的标准输出重定向到aa.log 这个文件中,而右边的 2>&1是把错误输出给到标准输出了,所以整体的意思就是把标准错误输出和标准输出一起重定向到aa.log 文件中。
那么 不能把右边的命令 2>&1 写到 左边吗?
[root@node2 sh]# ls -ltr aaa 2>&1 >aa.log
ls: 无法访问aaa: 没有那个文件或目录
[root@node2 sh]#
这样相当于把 ls -ltr 和 >aa.log 这个命令隔断了,无法实现日志写到aa.log 的功能。
举几个例子感受下描述符的使用:
1、ls -ltr 2>1 不会报没有2这个文件,但是会生成一个空文件1
[root@node2 test]# ls -ltr 2
ls: 无法访问2: 没有那个文件或目录
[root@node2 test]# ls -ltr 2>1
总用量 0
-rw-r--r-- 1 root root 0 4月 24 21:51 1
[root@node2 test]#
2、ls -ltr 2 2>1 :把没有2这个文件的报错输出到1这个文件里
[root@node2 test]# ls -ltr 2 2>1
[root@node2 test]# cat 1
ls: 无法访问2: 没有那个文件或目录
[root@node2 test]#
3、ls -ltr 2 2>&1 ,报错会输出到标准输出,而且不会生成1这个文件了
[root@node2 test]# ls -ltr 2 2>&1
ls: 无法访问2: 没有那个文件或目录
[root@node2 test]# ll
总用量 0
[root@node2 test]#
4、ls -ltr 2 >aa.log 2>&1 ,报错会重定向到标准输出,同时把标准输出重定向到aa.log 文件中:
[root@node2 test]# ls -ltr 2 >aa.log 2>&1
[root@node2 test]# ls -ltr
总用量 4
-rw-r–r-- 1 root root 47 4月 24 21:58 aa.log
[root@node2 test]# cat aa.log
ls: 无法访问2: 没有那个文件或目录
[root@node2 test]#