背景知识
Linux的重定向指的是[改变输入/输出的方向],一般情况下,我们都是从键盘读取用户输入的数据,然后再把数据拿到程序中使用,这就是标准的输入方向,反过来,程序也会产生数据,这些数据都是呈现在显示器上,这就是标准输出方向。 简单的说:
- 输入方向就是数据从哪里流向程序,数据默认从键盘流向程序,如果改变它的方向,数据就从其他地方流入,这就是输入重定向。
- 输出方向就是数据从程序流向哪里,数据默认从程序流向显示器,如果改变它的方向,数据就流向其他地方,这就是输出重定向。
Linux中与输入输出相关的文件描述符
文件描述符 | 文件名 | 类型 | 硬件 |
---|
0 | stdin | 标准输入文件 | 键盘 | 1 | stdout | 标准输出文件 | 显示器 | 2 | stdin | 标准错误输出文件 | 显示器 |
上述中是Linux中默认的标准输入、输出、错误输出。
Linux shell 输出重定向的目的
Linux shell中输出重定向的目的是为了控制指令的结果不再输出到显示器上,而是输出到其他文件,当然也包括不输出,也就是不生成nohup.out文件。
Linux Bash支持的输出重定向语法
类型 | 符号 | 作用 |
---|
标准输出重定向 | command >file | 以覆盖的方式,把command的正确输出结果输出到file文件中 | 标准输出重定向 | command >>file | 以追加的方式,把command的正确输出结果输出到file文件中 | 标准错误输出重定向 | command 2>file | 以覆盖的方式,把command的正确输出结果输出到file文件中(2错误输出文件描述符) | 标准错误输出重定向 | command 2>>file | 以追加的方式,把command的正确输出结果输出到file文件中(2错误输出文件描述符) | 正确输出和错误信息同步保存 | command >file 2>&1 | 以覆盖的方式,把正确输出和错误信息同时保存到同一个文件(file)中 | 正确输出和错误信息同步保存 | command >>file 2>&1 | 以追加的方式,把正确输出和错误信息同时保存到同一个文件(file)中 | 正确输出和错误信息同步保存 | command >file 2>file | 不推荐这种方式,因为会导致file被打开两次,引起资源竞争 |
注: 输出重定向的完整写法是 fd>file或者fd>>file,其中fd表示文件描述符,如果不写,默认为1,也就是标准输出,所以我们看到的一般都会省略不写。
/dev/null 知识点
在linux中,/dev/null代表linux的控设备,所有往这个设备里写入的内容都会被丢失,俗称“黑洞”。
2>&1 知识点
& 表示输出绑定,也就是重定向绑定,这条命令的作用是将错误输出(文件描述符2)和标准输出(文件描述符1)重定向到同一个地方。
>/dev/null 2>&1 同时使用分析
这其实是两条命令,只不过是告诉shell要连续执行,我们逐条分析一下重定向功能流程:
- /dev/null : 标准输出重定向到 /dev/null 即空设备文件,也就是黑洞中,结果就是将标准输出结果 丢弃。
- 2>&1 : 错误输出(文件描述符2)与标准输出(文件描述符1)重定向绑定到同一个地方,因为前一条指令中已经将标准输出重定向到黑洞,所以这里也会将错误输出也重定向到黑洞,结果就是忽略标准输出和错误输出,即输出结果丢弃。
注意,如果颠倒了2和1的位置,也就是 1>&2,起不到丢弃的作用,因为 '>'的语法是 '左’侧重定向’右’侧, 最后相当于将标准输出重定向到错误输出了。
为什么要重定向绑定
重定向绑定,从功能上看,其实是为了让两个输出都重定向到同一个地方,那么我们可否通过两次重定向来实现重定向绑定呢? 答案是否,因为如果采用两次重定向到一个地方,就会导致两个输出会抢占往out的管道,导致输出内容缺失或覆盖,也就是不同步,而且由于out文件被打开了2次,整体的IO效率也不高。
示例
0. 假设当前目录下只有1个文件 1.txt
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ tree
.
└── 1.txt
1. 执行 ls 1.txt 2.txt
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ ls 1.txt 2.txt
ls: cannot access '2.txt': No such file or directory
1.txt
由于没有2.txt,所以屏幕把报警信息也输出了。
2. 我们将输出结果重定位到一个文件里,然后查看文件
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ ls 1.txt 2.txt >out
ls: cannot access '2.txt': No such file or directory
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ ls
1.txt out
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ cat out
1.txt
这里我们省略了文件描述符,所以默认是1,也就是把标准输出重定向到out文件里,而且out文件里存放的是正确的结果。
3. 我们将输出结果中的“错误信息”重定向到out文件
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ ls 1.txt 2.txt 2>out
1.txt
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ ls
1.txt out
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ cat out
ls: cannot access '2.txt': No such file or directory
4. 所有输出结果丢弃
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ ls
1.txt
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ ls 1.txt 2.txt >/dev/null 2>&1
ubuntu@VM-0-17-ubuntu:/opt/test/0816$ ls
1.txt
可以看到,输出结果,无论是标准输出还是错误输出,都没有显示,因为都被丢弃了。
nohup组合
当我们想要启动程序,并将程序后台执行时,并且不想保留日志的,经常会使用重定向命令:
nohup ./app >/dev/null 2>&1 &
结合上面的知识点,相信能够很容易分析这条命令的含义。如果没有重定向,我们一般能看到一个 nohup的运行日志。
|