zoukankan      html  css  js  c++  java
  • 《Linux命令行与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/

  • 相关阅读:
    LeetCode 230. 二叉搜索树中第K小的元素(Kth Smallest Element in a BST)
    LeetCode 216. 组合总和 III(Combination Sum III)
    LeetCode 179. 最大数(Largest Number)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)
    指针变量、普通变量、内存和地址的全面对比
    MiZ702学习笔记8——让MiZ702变身PC的方法
    你可能不知道的,定义,声明,初始化
    原创zynq文章整理(MiZ702教程+例程)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3275683.html
Copyright © 2011-2022 走看看