首页 > 其他分享 >2>&1到底是什么意思?

2>&1到底是什么意思?

时间:2022-09-25 10:33:09浏览次数:42  
标签:文件 到底 什么 意思 标准 描述符 file 进程 table

java -jar snapshot.jar > snapshot.log 2>&1 &

写Java的朋友一定对上面的命令很熟悉,相信大部分人都知道>表示的是重定向,那么什么是重定向?2>&1又是什么意思?

要从根儿上说明这个问题,我们有必要好好理解一下「文件描述符」的概念。

1. 文件描述符

1.1. 什么是文件描述符

文件描述符(File descripter)就是一个整数,这个整数唯一标识了操作系统中某个被打开的“文件”。

1.2. 文件与I/O

说到“文件”必然离不开I/O。

很多人搞不明白I/O到底应该怎么理解,字面上就是输入/输出罢了,但是站在不同角度,其表示的含义也不一样。

站在计算机的角度,I/O表示的是计算机与外界的交互,交互的对象是硬件设备,输入输出自然也指的是和硬件之间的输入输出。

I/O设备

站在程序的角度,I/O的含义更宽泛,操作系统与所有能被当作文件的对象之间的交互就是I/O。

Linux的哲学思想是「一切皆文件」,文件(file,例如foo.txt)、管道(pipe)、网络(socket),甚至打印机、显示器、磁盘以及命令行(terminal)都算是文件。

文件描述符标识的就是这些文件。

文件描述符这个术语通常出现在Unix或类Unix系统中,比如Linux、MacOS以及BSD等。

在Windows系统中,他有另外一个响当当(或者臭名昭著)的名字——句柄(File handle)。

2. 文件描述符原理

2.1. 进程私有文件描述符表

每个进程可以打开多个文件,所以每个进程都会有一个私有的文件描述符表(file descriptors table)。

注:下文称file descriptors table中的每一个条目为file descriptor,称file descriptor中的整数为fd

需要注意的是,每个进程的fd 012已经被占用(下文会有解释),之后分配的每个进程的fd3开始。

file descripter table

进程级的描述符表的每一个条目记录了当前进程所有打开的文件的文件描述符,进程之间相互独立,例如一个进程使用了文件描述符99,另一个进程也可以用99

fd只是个数字而已,操作系统肯定需要根据这个数字来找到实际对应的文件。换句话说,file descripter肯定指向了某个表示真实文件的数据结构,或者能够再次根据这个数据结构来找到真实文件。

这个数据结构就是「全局文件表」。

2.2. 全局文件表

全局文件表(global file table),顾名思义,就是所有进程共享的一个数据结构。

当用户进程向内核发起一个针对文件的system call(比如open())时,内核将

  1. 允许进程访问;
  2. 向全局文件表(global file table)中插入一个条目,并向进程返回一个指向该条目的一个file descriptor
  3. 进程将file descriptor插入到file descriptors table,并返回其在file descriptors table中的下标,也就是fd

全局文件表

其实,根据global file table并不能直接找到对应文件进行操作,还需要根据其中的指针找到inode table的数据结构,进而再找到最终文件。但是这个技术细节对我们认识文件描述符没有什么作用,于是按下不表了。

2.3. 为什么需要文件描述符

进程进行系统调用的时候,内核为什么不直接返回指向文件的指针呢?反而多此一举加了个fd来引用文件。

原因是为了防止用户空间的程序随意读写操作系统内核的文件对象

如果内核直接返回内核中文件对象的地址给进程,进程便可以绕过内核,肆意对该文件进行操作,这样一来用户空间和内核空间的划分便如同虚设。

有了文件描述符之后,由于global file table处于内核空间中,用户即使拥有fd,也无法得到实际文件对象的地址,除非把fd作为系统调用的参数来使用,如此一来,控制权又回到了内核手中,也便达到了权限控制的目的。

fd是为了控制权限

3. 标准输入/标准输出/标准错误

前面说到,进程的文件描述符表的前3项已经被默认使用了。

  • 0:标准输入(stdin)
  • 1:标准输出(stdout)
  • 2:标准错误(stderr)

这些名词怎么理解?

我们在Java中使用new Scanner(System.in)接收从键盘的输入,使用System.out.println()向显示器写数据,对应C语言分别是scanf()printf()

需要明确的是,函数并非直接使用键盘和显示器,而是使用了标准输入和标准输出

说得再通俗一点就是,进程生来就有一个耳朵和两张嘴,耳朵用来接受标准输入里的数据,一个嘴往标准输出里边“说话”,另一张嘴往标准错误里边“吐槽”。

进程的三标准

函数并不知道数据从哪里来,也不关心数据要到哪里去,它们只需要从标准输入读数据,向标准输出标准错误中写数据就行了。

这就是抽象啊,朋友们!

默认情况下,操作系统会把所有键盘输入都发送到标准输入,会把从标准输出标准错误中读到数据发送到显示器。

为了方便表示,下文不再将全局文件表画出,而是用一张表来简化表示文件描述符和数据流之间的对应关系。

fd与数据流

接下来我们就可以解释文章开头提的问题了。

4. 输入输出重定向

标准输入/输出/错误在描述表的位置虽然是固定的,但他们指向的数据流是可以改变的。

重定向

java -jar snapshot.jar > snapshot.log 2>&1 &

这条指令的意思就是将snapshot.jar程序用>运算符重定向标准输出,由原本的指向显示器改为snapshot.log文件。

2>是用来重定向标准错误,因为标准错误在描述符表中的fd就是2,同样,其实重定向标准输出也可以表示为1>,不过一般简写为>

标准错误标准输出可以重定向到同一个地方,比如指令中的&1表示的就是标准输出2>&1的含义就是重定向标准错误到标准输出表示的数据流中。


完!

标签:文件,到底,什么,意思,标准,描述符,file,进程,table
From: https://www.cnblogs.com/chanmufeng/p/16727359.html

相关文章

  • 浏览器有哪些缓存?localStorage、sessionStorage、cookie的、session的区别是什么?
    浏览器的缓存机制提供了可以将用户数据存储在客户端的方式,可以利用cookie,session等跟服务器端进行数据交互1.保存方式cookie保存在浏览器端session保存在服务器端2.......
  • 什么是C语言
    什么是C语言?C语言是一门计算机语言计算机语言是什么呢?人和计算机交流的语言,如C/C++、Java、python 语言的发展?二进制语言(硬件-电-正电1/负电01010100101001100......
  • 为什么obj的方法属性里,this会指向Window?
    昨天遇到的一道题,问输出结果是什么?为什么?如何更改可以输出另一个name?varname="Tom"varobj={name:"Jerry",getName:function(){functionget(......
  • 为什么MySQL 默认隔离级别是RR,又被阿里设置为RC
    我们知道,我们可以通过这个命令查看数据库当前的隔离级别,MySQL默认隔离级别是RR. select@@tx_isolation; ANSI/ISOSQL定义的标准隔离级别有四种,从高到底依次为:可序......
  • Mac的蝶式键盘为什么会不舒服
    有些同学用mac的蝶式键盘感觉硬邦邦的,很不适应,因此吐槽mac键盘垃圾(包括我)。经过分析,得出一个结论:apple采用蝶式键盘试图改变用户的打字习惯。推荐使用按压式使用键盘。......
  • 神经网络----为什么使用向量化
    我们在处理大数据的时候,尽量避免使用for循环,那样会将低速度importnumpyasnpimporttimea=np.random.rand(1000000)b=np.random.rand(1000000)tic=time.ti......
  • 有意思的面试记录
    碰见一个很有意思的【百度面试】,和我好像hhh链接:https://www.bilibili.com/video/BV18Z4y1T7yZ/【类加载机制】类加载过程:加载+链接+初始化双亲委派--保证程序的稳......
  • 什么是二进制?
    二进制:逢二进一(计算机数据使用的)为什么要用二进制?只需要0和1就可以表示开和关10进制:0-916进制:0-9A-F8进制:0-7常见的存储单位最小单位是位即bit表示信息的最小......
  • 太公钓鱼的意思,太公钓鱼成语故事及出处
    【太公钓鱼的出处】太公钓鱼,出自《武王伐纣平话》卷下:“姜尚因命守时,直钩钓:‘负命者上钩来!’”【太公钓鱼的故事】公元前11世纪,八十岁的姜子牙见商纣王暴虐无道,弃官逃......
  • 四海之内皆兄弟的意思,四海之内皆兄弟成语故事及出处
    【四海之内皆兄弟的出处】四海之内皆兄弟,出自《论语·颜渊》:“君子敬而无失,与人恭而有礼,四海之内,皆兄弟也。”【四海之内皆兄弟的故事】孔子有一个弟子名叫司马牛。有......