在linux中我们时常能见到>,>>,>&,&>,&,&&,|,||,2>&1等符号,它们到底是什么?下面浅谈一下我的看法,如有不对的地方请大家及时指正!
在介绍上述符号表示什么之前,我们需要先知道在linux中有三种标准的文件描述符(也支持自定义),分别为:
举个简单的例子,当我们ls
一个不存在的文件时,会报错如下:
[zhxia@aemol ~]$ ls donot_exist.txt
ls: cannot access donot_exist.txt: No such file or directory
其中ls: cannot access donot_exist.txt:
No such file or directory
就是标准错误。
再来简单理解一下重定向的含义。比如我写了个test.py脚本。
[zhxia@aemol ~]$ cat test.py
print('Hello World')
可以看到脚本中只有一行代码。现在我在linux上用python test.py
运行脚本,它本来是要输出Hello World
到屏幕的,但现在我不让它直接输出到屏幕上,而是存在了output.log日志文件中,这就叫将标准输出重定向到output.log文件中。
那要实现这个目的,我们可以这样写:
[zhxia@aemol ~]$ python test.py >output.log
查看output.log文件可以发现已经将Hello World
写入了:
[zhxia@aemol ~]$ cat output.log
Hello World
用于将标准输出重定向至文件。如上面的例子,将Hello World
写入了output.log日志文件中而不是显示在屏幕上。
[zhxia@aemol ~]$ python test.py >output.log
[zhxia@aemol ~]$ cat output.log
Hello World
>>
和>
的区别在于>
是覆写文件而>>
是追加文件。即对于>
,当文件存在时会先删除原文件,再重新创建文件,然后把内容写入该文件;否则直接创建文件。而对于>>
,当文件存在时直接在文件末尾进行内容追加,不会删除原文件;否则直接创建文件。举个简单的例子如下:
[zhxia@aemol ~]$ python test.py >output.log
[zhxia@aemol ~]$ cat output.log
Hello World
zhxia@aemol ~]$ python test.py >>output.log
[zhxia@aemol ~]$ cat output.log
Hello World
Hello World
>&
和&>
在很多情况下是可以互换的,它们与>
的区别在于:>
只能将标准输出重定向(对于标准错误依然会显示在屏幕上),而>&
和&>
可以将标准输出或标准错误都重定向输出。
举例如下:
[zhxia@aemol ~]$ ls donot_exist.txt
ls: cannot access donot_exist.txt: No such file or directory
[zhxia@aemol ~]$ ls donot_exist.txt >output.log
ls: cannot access donot_exist.txt: No such file or directory
[zhxia@aemol ~]$ cat output.log
[zhxia@aemol ~]$ ls donot_exist.txt >&output.log
[zhxia@aemol ~]$ cat output.log
ls: cannot access donot_exist.txt: No such file or directory
[zhxia@aemol ~]$ ls donot_exist.txt &>output.log
[zhxia@aemol ~]$ cat output.log
ls: cannot access donot_exist.txt: No such file or directory
>&
后面既可以识别文件,可以识别文件描述符。
>&
后面接文件时,表示将标准输出和标准错误输出重定向至文件。[zhxia@aemol ~]$ ls donot_exist.txt >&output.log
[zhxia@aemol ~]$ cat output.log
ls: cannot access donot_exist.txt: No such file or directory
>&
后面接文件描述符时,表示将前面的文件描述符重定向至后面的文件描述符。例如,将标准错误文件描述符2重定向至标准输出文件描述符1:[zhxia@aemol ~]$ ls donot_exist.txt >output.log
ls: cannot access donot_exist.txt: No such file or directory
[zhxia@aemol ~]$ cat output.log
[zhxia@aemol ~]$ ls donot_exist.txt >output.log 2>&1
[zhxia@aemol ~]$ cat output.log
ls: cannot access donot_exist.txt: No such file or directory
&>
后面只可以识别文件。
&>
后面接文件时,可与>&
互相替换,都表示将标准输出和标准错误输出重定向至文件。[zhxia@aemol ~]$ ls donot_exist.txt &>output.log
[zhxia@aemol ~]$ cat output.log
ls: cannot access donot_exist.txt: No such file or directory
&>
后面接文件描述符时,表示将标准输出和标准错误输出重定向至与文件描述符同名的文件。[zhxia@aemol ~]$ ls donot_exist.txt >output.log
ls: cannot access donot_exist.txt: No such file or directory
[zhxia@aemol ~]$ cat output.log
[zhxia@aemol ~]$ ls donot_exist.txt >output.log 2&>1
[zhxia@aemol ~]$ cat output.log
[zhxia@aemol ~]$ cat 1
ls: cannot access donot_exist.txt: No such file or directory
ls: cannot access 2: No such file or directory
[zhxia@aemol ~]$ ls donot_exist.txt 2 &>1
[zhxia@aemol ~]$ cat 1
ls: cannot access donot_exist.txt: No such file or directory
ls: cannot access 2: No such file or directory
从上面的例子中可以看到ls donot_exist.txt >output.log 2&>1
与ls donot_exist.txt 2 &>1
等价。
&
表示将任务提交到后台运行。可以通过jobs
命令查看任务状态。
[zhxia@aemol ~]$python test.py &>output.log &
[1] 220546
[zhxia@aemol ~]$ jobs
[1]+ Done python test.py &>output.log
&&
表示表示前一条命令执行成功后,才执行后一条命令。
[zhxia@aemol ~]$python test.py && echo 'Wow!'
Hello World
Wow!
[zhxia@aemol ~]$ ls donot_exist.txt && echo 'Wow!'
ls: cannot access donot_exist.txt: No such file or directory
|
表示管道,即将上一条命令的输出,作为下一条命令的输入参数。
[zhxia@aemol ~]$ ls
output.log test.py
[zhxia@aemol ~]$ ls | grep test.py
test.py
||
表示表示前一条命令执行失败后,才执行后一条命令。
[zhxia@aemol ~]$ ls
output.log test.py
[zhxia@aemol ~]$ ls donot_exist.txt || echo 'Wow!'
ls: cannot access donot_exist.txt: No such file or directory
Wow!
2&>1
表示将标准错误输出重定向至标准输出。例如,先通过2&>1
将标准错误2输出重定向至标准输出1,再通过>
将标准输出1重定向到为output.log中,使得output.log中也包含了标准错误信息。不然仅有>output.log
的话,我们无法将标准错误存入output.log中。
[zhxia@aemol ~]$ ls donot_exist.txt >output.log
ls: cannot access donot_exist.txt: No such file or directory
[zhxia@aemol ~]$ cat output.log
[zhxia@aemol ~]$ ls donot_exist.txt >output.log 2>&1
[zhxia@aemol ~]$ cat output.log
ls: cannot access donot_exist.txt: No such file or directory