第一部分:Linux命令行
    《Linux命令行与shell脚本编程大全》 第一章:初识Linux shell
    《Linux命令行与shell脚本编程大全》 第二章:走进shell
    《Linux命令行与shell脚本编程大全》 第三章:基本的bash shell命令
    《Linux命令行与shell脚本编程大全》 第四章:更多的bash shell命令
    《Linux命令行与shell脚本编程大全》 第五章:使用Linux环境变量
    《Linux命令行与shell脚本编程大全》 第六章:理解Linux文件权限
    《Linux命令行与shell脚本编程大全》 第七章:管理文件系统
    《Linux命令行与shell脚本编程大全》 第八章:安装软件程序
    《Linux命令行与shell脚本编程大全》 第九章:使用编辑器

    第二部分:shell脚本编程基础
    《Linux命令行与shell脚本编程大全》 第十章:构建基本脚本
    《Linux命令行与shell脚本编程大全》 第十一章:使用结构化命令
    《Linux命令行与shell脚本编程大全》 第十二章:更多的结构化命令
    《Linux命令行与shell脚本编程大全》 第十三章:处理用户输入
    《Linux命令行与shell脚本编程大全》 第十四章:呈现数据
    《Linux命令行与shell脚本编程大全》 第十五章:控制脚本

    第三部分:高级shell编程
    《Linux命令行与shell脚本编程大全》 第十六章:创建函数
    《Linux命令行与shell脚本编程大全》 第十七章:图形化桌面上的脚本编程
    《Linux命令行与shell脚本编程大全》 第十八章:初识sed和gawk
    《Linux命令行与shell脚本编程大全》 第十九章:正则表达式
    《Linux命令行与shell脚本编程大全》 第二十章:sed进阶
    《Linux命令行与shell脚本编程大全》 第二十一章:gawk进阶
    《Linux命令行与shell脚本编程大全》 第二十二章:使用其他shell

    第四部分:高级shell脚本编程主题
    《Linux命令行与shell脚本编程大全》 第二十三章:使用数据库
    《Linux命令行与shell脚本编程大全》 第二十四章:使用Web
    《Linux命令行与shell脚本编程大全》 第二十五章:使用E-mail
    《Linux命令行与shell脚本编程大全》 第二十六章:编写脚本实用工具
    《Linux命令行与shell脚本编程大全》 第二十七章:shell脚本编程进阶


    第十四章:呈现数据

    理解输入与输出

    标准文件描述符

    文件描述符 缩写 描述
    0 STDIN 标准输入
    1 STDOUT 标准输出
    2 STDERR 标准错误

    1.STDIN

    代表标准输入。对于终端界面来说,标准输入是键盘

    使用输入重定向符号(<)时,Linux会用重定向指定的文件来替换标准输入文件描述符

    2.STDOUT

    代表标准输出。对于终端界面来说,标准输出是屏幕

    3.STDERR

    代表标准错误输出。 默认情况下,STDOUT文件描述符和STDERR文件描述符指向同样的地方,即显示器。

    重定向STDOUT并不会自动重定向STDERR

    重定向错误 & 重定向错误和错误数据

    在使用重定向符号时定义STDERR文件描述符就可以重定向错误输出。

      $ ls none 2> err_log
     

    重定向错误和正常输出,需要用两个重定向符号

      ls 3152.pdf none 1> temp1 2> temp2
     

    注意:不能使用这种方法将他们重定向到同一个文件中,一个重定向会覆盖另一个,所以不会正常工作。

    想要将其重定向到同一个文件,可以使用重定向符号“ &> ”(只能在bash中使用)

      ls 3152.pdf none &> temp
     

    关于重定向更详尽的讲解请参看( #1

    在脚本中重定向输出

    临时重定向

      echo "error message" >&2
     

    在重定向符号后面加上and符号以及文件描述符即可

    这样就将上面的log输出到标准错误中(当然,还是黑字不是红字)

    永久重定向

    用exec命令告诉shell脚本执行期间重定向某个文件描述符

      #!/bin/bash
    exec 1>ok
    exec 2>err
    
    echo "this is right"
    echo "this is wrong" >&2
     

    注意:上面即使把STDOUT重定向了,依然可以将echo重定向到STDERR

    在脚本中重定向输入

      exec 0< testfile
     

    创建自己的重定向

    创建输出文件描述符

      exec 3>mylog
    echo "this is my log" >&3
     

    同上面一模一样,只是文件描述符换成了3-8

    重定向文件描述符

    将已经重定向的文件描述符恢复:

    比如我们要恢复标准输出,基本的思路就是,使用一个文件描述符定向到标准输出,然后再把标准输出定向到其他地方,比如文件。当想把标准输出重定向回来的时候,只需将他重定向到之前使用的文件描述符那里即可。

      #!/bin/bash
    exec 3>&1
    exec 1>temp_log
    echo "you can't see me!"
    exec 1>&3
    echo "Now, you can see me."
     

    创建输入文件描述符

    与上面方法完全一致

      exec 4<&0
    exec 0<file1
    exec 0<&4
     

    创建读写文件描述符

    在向同一个文件中进行读取数据、写入数据操作时,shell会维护一个内部指针,指明现在指向什么位置。

    任何读或写都会从文件指针上次保存的位置开始。

      #!/bin/bash
    
    exec 3<> test.txt
    read line <&3
    echo "$line"
    echo "This a new line." >&3
     

    其中的test.txt为

      $ cat test.txt
    This is the first line.
    This is the second line.
    This the third line.
     

    执行上面的脚本,虽然控制台输出显得一切正常,但是并不会在test.txt末尾加一行

    因为之前读取了第一行,所以输入的时候会输入到第二行,把之前第二行的内容覆盖掉,显得结果变得有些诡异

      $ cat test.txt
    This is the first line.
    This a new line.
    d line.
    This the third line.
     

    关闭文件描述符

    如果你创建了新的输入或输出文件描述符,shell会在脚本退出时自动关闭他们。

    手动关闭文件描述符,则要将其重定向到特殊符号&-

    当关闭了文件描述符之后,如果再使用它,就会报错。

      #!/bin/bash
    exec 3> test.txt
    echo "This a new line." >&3
    exec 3>&-
    echo "This another line." >&3
     

    执行后结果:

      $ file_descriptor_test 
    ./file_descriptor_test: line 5: 3: Bad file descriptor
     

    如果之后在脚本中打开了同一个输出文件,文件原有内容会被覆盖。

    列出打开的文件描述符

    可以使用lsof命令。如果普通用户要用lsof命令,那么需要使用全路径。

    -a:对其他两个选项结果执行布尔AND运算

    -p:指定进程($$指当前进程)

    -d:指定文件描述符几个

      $ lsof -a -p $$ -d 0,1,2
    COMMAND  PID        USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    bash    1929 su1216    0u   CHR  136,0      0t0    3 /dev/pts/0
    bash    1929 su1216    1u   CHR  136,0      0t0    3 /dev/pts/0
    bash    1929 su1216    2u   CHR  136,0      0t0    3 /dev/pts/0
     

    相应的列含义为:

    描述
    COMMAND 正在运行的命令名的前9个字符
    PID 进程的PID
    USER 进程属主的登录名
    FD 文件描述符数目以及访问类型(r=读,w=写,u=读写)
    TYPE 文件的类型(CHR=字符型,BLK=块型,DIR=目录,REG=常规文件)
    DEVICE 设备的设备号(主设备号和从设备号)
    SIZE 文件大小(如果有的话)
    NODE 本地文件的节点数
    NAME 文件名

    与STDIN、STDOUT和STDERR关联的文件类型是字符型。因为STDIN、STDOUT和STDERR文件描述符都指向终端,所以输出文件的名称就是终端的设备名。 所有3种标准文件都支持读和写。

      #!/bin/bash
    exec 3> test.txt
    exec 4< test.txt
    exec 5<> test.txt
    
    /usr/bin/lsof -a -p $$ -d 0,1,2,3,4,5
     

    下面为输出结果:

      $ file_descriptor_test 
    COMMAND     PID        USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
    file_desc 13421 su1216    0u   CHR  136,1      0t0       4 /dev/pts/1
    file_desc 13421 su1216    1u   CHR  136,1      0t0       4 /dev/pts/1
    file_desc 13421 su1216    2u   CHR  136,1      0t0       4 /dev/pts/1
    file_desc 13421 su1216    3w   REG    8,7        0 3039280 /home/su1216/android/source/linux_learned/test.txt
    file_desc 13421 su1216    4r   REG    8,7        0 3039280 /home/su1216/android/source/linux_learned/test.txt
    file_desc 13421 su1216    5u   REG    8,7        0 3039280 /home/su1216/android/source/linux_learned/test.txt
     

    阻止命令输出

    可以将输出发送给位桶(/dev/null), 发给到它的任何东西都会消失

    关于位桶更多内容参见( #1

    创建临时文件

    Linux使用/tmp目录作为临时目录,当系统启动时,Linux会自动删除目录下所有文件

    系统上任何账户都有权限在/tmp中读写。

    mktemp命令可以在/tmp中创建一个唯一的临时文件,不使用默认的umask值。文件的读写权限将会分配给文件的属主,并将你设置为文件的属主,其他人无法访问,root除外。

    创建本地临时文件

    默认情况下,mktemp会在本地目录中创建临时文件

    mktemp tmp.XXXXXXXXXX

    至少为3个X

      $ mktemp abc.XX
    mktemp: too few X's in template `abc.XX'
    $ mktemp abc.XXX
    abc.84E
     

    输出即为新建立的文件名,这样就可以引用此文件

    创建多个临时文件,mktemp会保证文件的唯一性

    在/tmp目录下创建临时文件

    mktemp -t tmp.XXXXXXXXXX

    使用-t选项即可

      $ mktemp -t abc.XXX
    /tmp/abc.z20
     

    输出为临时文件的全路径

    创建临时目录

    mktemp -d tmp.XXXXXXXXXX

    使用-d选项即可

    记录消息

    tee命令相当于管道的T型接头,它将从STDIN过来的数据同时发给两个目的地,一个是STDOUT,另一个是tee命令所指定。

      $ date | tee test.txt
    2013年 08月 21日 星期三 21:12:28 CST
    $ cat test.txt
    2013年 08月 21日 星期三 21:12:28 CST
     

    tee默认会覆盖指定文件中的内容, 如果想追加,那么要使用-a选项

    1.第十五章:标准I/O:重定向和管道

    转贴请保留以下链接

    本人blog地址

    http://su1216.iteye.com/

    http://blog.csdn.net/su1216/