• Shell编程—数据展示


    1.标准文件描述符

    Linux用文件描述符(file descriptor)来标识每个文件对象。文件描述符是一个非负整数,可以唯一标识会话中打开的文件。每个进程一次 多可以有九个文件描述符。出于特殊目的,bash shell保留了前三个文件描述符(0、1和2):

    文件描述符

    缩  写

    描  述

    0

    STDIN

    标准输入

    1

    STDOUT

    标准输出

    2

    STDERR

    标准错误

    1. STDIN代表shell的标准输入。对终端界面来说,标准输入是键盘。

    2. STDOUTSTDOUT文件描述符代表shell的标准输出。在终端界面上,标准输出就是终端显示器。

    3. STDERRSTDERR文件描述符处理错误消息。STDERR文件描述符代表shell的标准错误输出。

    1.1重定向错误

    1. 只重定向错误

    $ ls -al test badtest test2 2> test5
    -rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2
    $ cat test5 
    ls: cannot access test: No such file or directory 
    ls: cannot access badtest: No such file or directory

    2. 重定向错误和数据

    $ ls -al test test2 test3 badtest 2> test6 1> test7
    $ cat test6 
    ls: cannot access test: No such file or directory 
    ls: cannot access badtest: No such file or directory
    $ cat test7
    -rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2
    -rw-rw-r-- 1 rich rich   0 2014-10-16 11:33 test3

     

    2在脚本中重定向输出

    有两种方法来在脚本中重定向输出:

    •  临时重定向行输出
    • 永久重定向脚本中的所有命令

    2.1 临时重定向

    如果有意在脚本中生成错误消息,可以将单独的一行输出重定向到STDERR。你所需要做的是使用输出重定向符来将输出信息重定向到STDERR文件描述符。在重定向到文件描述符时,你必须在文件描述符数字之前加一个&:

    echo "This is an error message" >&2

    这行会在脚本的STDERR文件描述符所指向的位置显示文本,而不是通常的STDOUT。

    2.2永久重定向

    如果脚本中有大量数据需要重定向,那重定向每个echo语句就会很烦琐。这时可以用exec命令告诉shell在脚本执行期间重定向某个特定文件描述符:

    $ cat test10
    #!/bin/bash
    # redirecting all output to a file 
    exec 1>testout
     echo "This is a test of redirecting all output" 
     echo "from a script to another file." 
     echo "without having to redirect every individual line"
     
    $ ./test10
    $ cat testout
    This is a test of redirecting all output 
    from a script to another file.
    without having to redirect every individual line

    exec命令会启动一个新shell并将STDOUT文件描述符重定向到文件。脚本中发给STDOUT的所有输出会被重定向到文件。

    3在脚本中重定向输入

    exec命令允许你将STDIN重定向到Linux系统上的文件中:

    exec 0< testfile

    例子:

    $ cat test12
    #!/bin/bash
    # redirecting file input
     exec 0< testfile 
     count=1 
     while read line 
     do 
        echo "Line #$count: $line"    
        count=$[ $count + 1 ] 
     done
     
    $ ./test12
    Line #1: This is the first line. 
    Line #2: This is the second line. 
    Line #3: This is the third line.

     

    4创建自己的重定向

    在脚本中重定向输入和输出时,并不局限于这3个默认的文件描述符。在shell 中 多可以有9个打开的文件描述符。其他6个从3~8的文件描述符均可用作输入或输出重定向。你可以将这些文件描述符中的任意一个分配给文件,然后在脚本中使用它们。

    创建输出文件描述符

    可以用exec命令来给输出分配文件描述符。和标准的文件描述符一样,一旦将另一个文件描述符分配给一个文件,这个重定向就会一直有效,直到你重新分配。

    $ cat test13
    #!/bin/bash
    # using an alternative file descriptor
     exec 3>test13out
     echo "This should display on the monitor" 
     echo "and this should be stored in the file" >&3 
     echo "Then this should be back on the monitor"
     
    $ ./test13
    This should display on the monitor
    Then this should be back on the monitor
    $ cat test13out 
    and this should be stored in the file

    这个脚本用exec命令将文件描述符3重定向到另一个文件。当脚本执行echo语句时,输出内容会像预想中那样显示在STDOUT上。但你重定向到文件描述符3的那行echo语句的输出却进入了另一个文件。

     

    5列出打开的文件描述符

    lsof命令会列出整个Linux系统打开的所有文件描述符。lsof命令位于/usr/sbin目录。

    该命令会产生大量的输出。它会显示当前Linux系统上打开的每个文件的有关信息。这包括后台运行的所有进程以及登录到系统的任何用户。

    常用的有-p和-d,前者允许指定进程ID(PID),后者允许指定要显示的文件描述符编号。

    要想知道进程的当前PID,可以用特殊环境变量$$(shell会将它设为当前PID)。-a选项用来对其他两个选项的结果执行布尔AND运算,这会产生如下输出。

    $ /usr/sbin/lsof -a -p $$ -d 0,1,2
    COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
    bash    3344 rich    0u   CHR  136,0         2 /dev/pts/0 
    bash    3344 rich    1u   CHR  136,0         2 /dev/pts/0 
    bash    3344 rich    2u   CHR  136,0         2 /dev/pts/0

    lsof的默认输出中有7 列信息:

    描  述

    COMMAND

    正在运行的命令名的前9个字符

    PID

    进程的PID

    USER

    进程属主的登录名

    FD

    文件描述符号以及访问类型(r代表读,w代表写,u代表读写)

    TYPE

    文件的类型(CHR代表字符型,BLK代表块型,DIR代表目录,REG代表常规文件)

    DEVICE

    设备的设备号(主设备号和从设备号)

    SIZE

    如果有的话,表示文件的大小

    NODE

    本地文件的节点号

    NAME

    文件名

    STDIN STDOUT STDERR   STDIN STDOUT STDERR 件描述符都指向终端,所以输出文件的名称就是终端的设备名。

    $ cat test18 
    #!/bin/bash 
    # testing lsof with file descriptors 
     exec 3> test18file1 
     exec 6> test18file2 
     exec 7< testfile 
    /usr/sbin/lsof -a -p $$ -d0,1,2,3,6,7 
    
    $ ./test18 
    COMMAND  PID USER   FD   TYPE DEVICE SIZE   NODE NAME 
    test18  3594 rich    0u   CHR  136,0           2 /dev/pts/0 
    test18  3594 rich    1u   CHR  136,0           2 /dev/pts/0 
    test18  3594 rich    2u   CHR  136,0           2 /dev/pts/0 
    18      3594 rich    3w   REG  253,0    0 360712 /home/rich/test18file1 
    18      3594 rich    6w   REG  253,0    0 360715 /home/rich/test18file2 
    18      3594 rich    7r   REG  253,0   73 360717 /home/rich/testfile 

    6阻止命令输出

    null文件跟它的名字很像,文件里什么都没有。可以将STDERR重定向到一个叫作null文件的特殊文件。shell输出到null文件的任何数据都不会保存,全部都被丢掉了。比如:

    $ ls -al > /dev/null $ cat /dev/null

    下面是避免出现错误消息,也无需保存它们的一个常用方法:

    $ ls -al badfile test16 2> /dev/null 
    -rwxr--r--    1 rich     rich          135 Oct 29 19:57 test16*

    可以在输入重定向中将/dev/null作为输入文件。由于/dev/null文件不含有任何内容,通常用它来快速清除现有文件中的数据,而不用先删除文件再重新创建。

    $ cat testfile
    This is the first line.
    This is the second line.
    This is the third line.
    $ cat /dev/null > testfile
    $ cat testfile

    文件testfile仍然存在系统上,但现在它是空文件。

     

    7创建临时文件

    mktemp命令可以在/tmp目录中创建一个唯一的临时文件。shell会创建这个文件,但不用默认的umask值。

    7.1创建本地临时文件

    默认情况下,mktemp会在本地目录中创建一个文件。要用mktemp命令在本地目录中创建一个临时文件,你只要指定一个文件名模板就行了。模板可以包含任意文本文件名,在文件名末尾加上6个X就行了:

    $ mktemp testing.XXXXXX
    $ ls -al testing* 
    -rw-------   1 rich     rich      0 Oct 17 21:30 testing.UfIi13

    mktemp命令会用6个字符码替换这6个X,从而保证文件名在目录中是唯一的。

     

    mktemp命令的输出正是它所创建的文件的名字。在脚本中使用mktemp命令时,可能要将文件名保存到变量中,这样就能在后面的脚本中引用了。

    $ cat test19
    #!/bin/bash
    # creating and using a temp file
     tempfile=$(mktemp test19.XXXXXX)
     exec 3>$tempfile
     echo "This script writes to temp file $tempfile"
     echo "This is the first line" >&3 
     echo "This is the second line." >&3 
     echo "This is the last line." >&3 
     exec 3>&-
     echo "Done creating temp file. The contents are:" 
     cat $tempfile 
     rm -f $tempfile 2> /dev/null
     
    $ ./test19
    This script writes to temp file test19.vCHoya 
    Done creating temp file. The contents are:
    This is the first line
    This is the second line.
    This is the last line.
    $ ls -al test19*
    -rwxr--r--    1 rich     rich          356 Oct 29 22:03 test19*

    7.2/tmp 目录创建临时文件

    -t选项会强制mktemp命令来在系统的临时目录来创建该文件。mktemp命令会返回用来创建临时文件的全路径,而不是只有文件名。

    $ cat test20
    #!/bin/bash
    # creating a temp file in /tmp
     tempfile=$(mktemp -t tmp.XXXXXX)
     echo "This is a test file." > $tempfile 
     echo "This is the second line of the test." >> $tempfile
     echo "The temp file is located at: $tempfile" 
     cat $tempfile 
     rm -f $tempfile
     
    $ ./test20
    The temp file is located at: /tmp/tmp.Ma3390 
    This is a test file.
    This is the second line of the test.

    7.3创建临时目录

    -d选项告诉mktemp命令来创建一个临时目录而不是临时文件。

    $ cat test21
    #!/bin/bash
    # using a temporary directory
     tempdir=$(mktemp -d dir.XXXXXX) 
     cd $tempdir 
     tempfile1=$(mktemp temp.XXXXXX) 
     tempfile2=$(mktemp temp.XXXXXX) 
     exec 7> $tempfile1 
     exec 8> $tempfile2
    echo "Sending data to directory $tempdir" 
    echo "This is a test line of data for $tempfile1" >&7 
    echo "This is a test line of data for $tempfile2" >&8
    
    $ ./test21
    Sending data to directory dir.ouT8S8 
    $ cd dir.ouT8S8
    $ cat temp.N5F3O6
    This is a test line of data for temp.N5F3O6
    $ cat temp.SQslb7
    This is a test line of data for temp.SQslb7
  • 相关阅读:
    【Unity与23种设计模式】命令模式(Command)
    【Unity3D与23种设计模式】组合模式(Composite)
    【Unity3D与23种设计模式】享元模式(Flyweight)
    【Unity3D与23种设计模式】建造者模式(Builder)
    【Unity3D与23种设计模式】工厂方法模式(Factory Method)
    【Unity3D与23种设计模式】模板方法模式(Template Method)
    【Unity3D与23种设计模式】策略模式(Strategy)
    【Unity3D与23种设计模式】桥接模式(Bridge)
    C# 清空数组Array.Clear
    Unity 修改windows窗口的标题
  • 原文地址:https://www.cnblogs.com/ericz2j/p/12045621.html
Copyright © 2020-2023  润新知