Linux标准输出重定向及标准错误重定向

你可能遇到了如下问题:

[root@localhost shell]# ls -l badfile > error.log
ls: 无法访问badfile: 没有那个文件或目录
[root@localhost shell]# cat error.log

当命令生成错误消息时,shell并未将错误消息重定向到输出重定向文件。shell创建了输出重
定向文件,但错误消息却显示在了显示器屏幕上。注意,在显示test3文件的内容时并没有任何错
误。test3文件创建成功了,只是里面是空的。

在项目中,我们经常需要查看日志文件的错误信息,来进行排查问题,也就是说,我们需要解决如何把错误信息保存到文件中,而不是默认显示在显示器上。

只重定向错误

STDERR文件描述符为2,我们可以在重定向符号前加上2,如下:
[root@localhost shell]# ls -l badfile 2> nginx.log
[root@localhost shell]# cat nginx.log 
ls: 无法访问badfile: 没有那个文件或目录

为什么说如上只是重定向错误呢,为了证明,我们列出一个已存在加不存在的文件

[root@localhost shell]# ls
error.log  hello.txt  nginx.log  test.sh
[root@localhost shell]# ls -l hello.txt badfile 2> apache.log
-rw-r--r-- 1 root root 36 1月  11 08:48 hello.txt
[root@localhost shell]# cat apache.log 
ls: 无法访问badfile: 没有那个文件或目录

可以看到,hello.txt信息并没有存储到apache.log文件中,而是显示到了显示器中,apache.log文件只是存储了错误信息。

重定向错误和数据

如果想重定向错误和正常输出,必须用两个重定向符号。需要在符号前面放上待重定向数据
所对应的文件描述符,然后指向用于保存数据的输出文件。

如下所示:将正确的日志和错误的日志进行分离

[root@localhost shell]# ls
hello.txt  test.sh
[root@localhost shell]# ls -l aa hello.txt badfile 2> error.log 1>access.log
[root@localhost shell]# cat error.log 
ls: 无法访问aa: 没有那个文件或目录
ls: 无法访问badfile: 没有那个文件或目录
[root@localhost shell]# cat access.log 
-rw-r--r-- 1 root root 36 1月  11 08:48 hello.txt

数据和错误重定向到同一个文件

使用&>重定向符号将STDERR和STDOUT的输出重定向到同一输出文件。

[root@localhost shell]# ls
hello.txt
[root@localhost shell]# ls -l aa hello.txt badfile &> all.log
[root@localhost shell]# cat all.log 
ls: 无法访问aa: 没有那个文件或目录
ls: 无法访问badfile: 没有那个文件或目录
-rw-r--r-- 1 root root 36 1月  11 08:48 hello.txt

不知各位有没有注意到一个问题,badfile的错误输出在hello.txt之前,这是因为shell自动赋予了错误消息更高的优先级。

临时重定向(>&2)

[root@localhost shell]# cat test.sh 
#!/bin/bash
echo "This is an error" >&2
echo "This is normal output"

如果以如下方式执行,则两句都会输出

[root@localhost shell]# ./test.sh 
This is an error
This is normal output

如果执行的时候又进行了错误重定向,则正常输出一句到显示器,错误日志则写入错误文件中,达到了分离的效果。

[root@localhost shell]# ./test.sh 2> error.log
This is normal output
[root@localhost shell]# cat error.log 
This is an error

永久重定向(exec)

[root@localhost shell]# cat test.sh 
#!/bin/bash

exec 2>error.log
echo "This is the start of the script"

exec 1>access.log
echo "This output should go to the access.log"
echo "but this should go to the error.log" >&2

脚本中,exec将STDERR输出重定向到error.log,所以执行This is the start of the script正常语句将输出到显示器,接下来,把STDOUT重定向输出到access.log中,所以This output should go to the access.log会显示到access.log文件中,但你仍然可以将echo语句输出发给STDERR,所以but this should go to the error.log最终会写入到error.log

运行结果如下:

[root@localhost shell]# ./test.sh 
This is the start of the script
[root@localhost shell]# cat access.log 
This output should go to the access.log
[root@localhost shell]# cat error.log 
but this should go to the error.log

重定向文件描述符

默认linux允许最多9个文件描述符,0,1,2这三个已经被系统占用,其他3-9我们可以自定义文件描述符。

以下是一个常用技巧,临时重定向输出。

[root@localhost shell]# cat test.sh 
#!/bin/bash
exec 3>&1
exec 1>access.log

echo "This should store in the access.log file"
echo "along with this line."

exec 1>&3
echo "This msg should be back to normal"

如上脚本临时把输出输出到文件中,然后又恢复默认的显示(显示器)
运行如下:

[root@localhost shell]# ./test.sh 
This msg should be back to normal
[root@localhost shell]# cat access.log 
This should store in the access.log file
along with this line.

你可能感兴趣的:(linux)