Shell I/O重定向

在 Sun 02 March 2014 发布于 Shell 分类

简单的说linux下I/O重定向就是把文件、命令、可执行程序、脚本等的输出作为另一个文件、命令、可执行程序、脚本做其输入数据.

每个打开的文件都分配了一个唯一的文件描述符,这个文件描述是一个整数,依次递增, 类似C语言中的open函数。 代表标准输入(stdin), 标准输出(stdout), 标准错误输出(stderr)的文件描述符分别是0、1、2。

通过>>>来进行输出重定向,对于输出重定向到文件, 需要注意的是 >会截断文件使其长度为0, 也就是说是空文件, 如果文件不存在的话,就会创建一个文件。命令> README.md:> README.md,及 touch README.md的作用一样都是创建一个空文件README.md,其中第二个命令中的:只是一个占位符,没有实际的输出产生。 而>>会把输出追加到文件末尾, 如果文件不存在,也会创建文件。

下面的例子是把输出结果重定向到文件中 在写shell脚本的时候可以吧stdoutstderr重定向到文件中供进行日志分析:

    # 把标准输出重定向(或者重定向且追加)到filename中
    1 > filename
    1 >> filename
    # 把标准错误输出重定向(或者重定向且追加)到filename中
    2 > filename
    2 >> filename
    # 把标准错误输出和标准输出重定向(或者重定向且追加)到文件filename
    & > filename
    & >> filename

一般在做定时任务的是后,在定时任务的配置文件里配置了要执行的命令后一般会在后面加上... >> /path/to/xxxx.log 2>&1,这个语句的意思是把定时任务的标准错误输出重定向到标准输出,然后把标准输出重定向到/path/to/xxxx.log文件中。 形如m>&n是文件描述符之间重定向,其中mn都是合法的文件描述符。如果m没有给出,默认重定向标准输出。

通过<来重定向输入, 用法和>基本相同,只是把>换成了<

打开文件, 并指定具体的文件描述符:

    #打开文件filename进行读写, 并且把文件描述符j绑定到该文件, 如果文件文件不存在, 则创建文件, j默认为0
[j]<> filename

关闭文件

    #关闭输入文件描述符n
    n<&-
    #关闭输出文件描述符n
    n>&-

exec < filename 命令会吧标准输入重定向到一个文件filename, 这个命令执行之后所有的标准输入都来自filename, 而不是来自之前的标准输入(通常是键盘输入)。在进行这个操作的时候,建议需要把标准输入重定向到一个没有用过的文件描述符上,待后面进行恢复标准输入。

#!/bin/bash
#这里假设文件描述符6为最新最小没有使用的文件描述符
exec 6<&0
exec < filename
#do the work
#把输入描述符恢复,并关闭之前的文件描述符
exec 0<&6 6<&-

exit 0

同理 exec > filename把 输出都重定向到文件filename, 这个命令执行之后的所有命令的输出都会输出到file中, 那么这在执行定时脚本的时候打印日志很有用

today=`date +%Y%m%d`
exec 1>> /path/to/logs/${today}.log
exec 2>> /path/to/logs/${today}.log
#do the work