简介
内核(kernel)利用文件描述符(file descriptor)来访问文件。
1.系统为每一个进程维护了一个文件描述符表,该表的值都是从0开始的,所以在不同的进程中你会看到相同的文件描述符,这种情况下相同文件描述符有可能指向同一个文件,也有可能指向不同的文件
2.每一个文件描述符会与一个打开文件相对应,同时,不同的文件描述符也会指向同一个文件。相同的文件可以被不同的进程打开也可以在同一个进程中被多次打开。
3.习惯上,标准输入(standard input)的文件描述符是 0,标准输出(standard output)是 1,标准错误(standard error)是 2
0,1,2分别对应标准输入,标准输出,错误输出
3以及以后分别对应打开的文件
文件描述符最大限制
查看一个进程最多能容纳文件描述符的数量
[root@VM_158_86_centos ~]# ulimit -n
100001
临时修改文件描述符数命令
[root@VM_158_86_centos ~]# ulimit -HSn 65536
[root@VM_158_86_centos ~]# ulimit -n
165536
永久修改文件描述符数
[root@VM_158_86_centos ~]# cat /etc/security/limits.conf
# /etc/security/limits.conf
root soft nofile 100001
root hard nofile 100002
文件句柄、文件描述符与进程的关系
文件句柄与文件描述符的作用:帮助系统或进程找到文件对象在内存的位置
普通打开文件
文件共享
父进程与子进程普通打开文件
子进程会fork父进程,所以会和父进程的文件描述符表相同,因此共享父进程已经打开的文件
核心思想:
因为每个进程都有自己HANDLE的存储空间;如果是同一个进程的线程,因为同基于I/O多路复用的流一样,多个线程运行在单一进程的上下文中,共享这个进程虚拟地址空间的整个内容,包括它的代码、数据、堆、共享库和打开的文件(句柄)
关于2>&1的含义
0是标准输入 1是标准输出 2是标准错误输出
含义:将标准错误输出重定向到标准输出
符号>&是一个整体,不可分开,分开后就不是上述含义了。
比如有些人可能会这么想:2是标准错误输入,1是标准输出,>是重定向符号,那么"将标准错误输出重定向到标准输出"是不是就应该写成"2>1"就行了?是这样吗?
如果是尝试过,你就知道2>1的写法其实是将标准错误输出重定向到名为"1"的文件里去了
写成2&>1也是不可以的
为什么2>&1要放在后面
考虑如下一条shell命令
nohup java -jar app.jar >log 2>&1 &
为什么2>&1一定要写到>log后面,才表示标准错误输出和标准输出都定向到log中?
我们不妨把1和2都理解是一个指针,然后来看上面的语句就是这样的:
本来1----->屏幕 (1指向屏幕)
执行>log后, 1----->log (1指向log)
执行2>&1后, 2----->1 (2指向1,而1指向log,因此2也指向了log)
再来分析下
nohup java -jar app.jar 2>&1 >log &
本来1----->屏幕 (1指向屏幕)
执行2>&1后, 2----->1 (2指向1,而1指向屏幕,因此2也指向了屏幕)
执行>log后, 1----->log (1指向log,2还是指向屏幕)
所以这就不是我们想要的结果。
参考地址