SHELL脚本学习总结(第四话)数据重定向

@@@    文件描述符

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

文件描述符用途stdio流

0

标准输入STDIN

1

标准输出STDOUT
2错误错误输出STDERR

①STDIN标准输入

对终端界面来说,标准输入是键盘;也可以使用重定向符号 < ,用重定向指定的文件来代替标准输入文件描述符。

# echo "Super robot war."      ###键盘输入
Super robot war.

# cat file
ONE
TWO

# cat < file                  ###使用<后file中内容代替了键盘输入
ONE
TWO

②STDOUT标准输出

在终端界面上,标准输出就是显示器。也可以使用重定向符号 > file(覆盖原有内容)>>file(追加到原有内容之后)。

# cat file
ONE
TWO

# echo "Super robot war." >> file      ###追加到了最后
# cat file                
ONE
TWO
Super robot war.


# echo "Hellow kitty." > file          ###覆盖掉了原有内容
# cat file 
Hellow kitty.

③STDERR标准错误

默认情况下,标准错误也显示到显示器上。但STDERR不会自动重定向,因此需要设置2>file将错误信息输出到file中。

# ls bbb
ls: cannot access 'bbb': No such file or directory

# ls bbb 2>errfile                        ###重定向后屏幕上无任何输出,因为已经输出到了errfile
# cat errfile
ls: cannot access 'bbb': No such file or directory



# ls errfile bbb
ls: cannot access 'bbb': No such file or directory    ###错误输出(bash中会优先输出)
errfile                                               ###正常输出


# ls errfile bbb 1>stdfile 2>>errfile    ###可以用 2>or>>file1 1>or>>file2分别将标准错误和标
        (屏幕上无任何输出)                    准输出重定向到不同的文件中
# cat stdfile
errfile
# cat errfile
ls: cannot access 'bbb': No such file or directory
ls: cannot access 'bbb': No such file or directory


# ls errfile bbb &>jizhong               ###也可以使用&>将所有输出都输出到同一个文件内
# cat jizhong   
ls: cannot access 'bbb': No such file or directory    
errfile

 

@@@    在脚本中重定向输出输入

&&&    临时重定向

在脚本中重定向到文件描述符时,必须在文件描述符数字之前加&

# vim cdx001.sh 
#!/bin/bash
echo "this is an error" >&2    ###重定向至标准错误输出
echo "this is normal output"

执行结果
# ./cdx001.sh                   ###默认情况下STDERR也会输出到屏幕上
this is an error
this is normal output

# ./cdx001.sh 2>errfile       ###将错误重定向到errfile 
this is normal output        ###只显示了正确的输出

# cat shellerr
this is an error

&&&    永久重定向 exec

exec命令可以在shell在脚本执行期间重定向某个特定文件描述符。

vim cdx002.sh
#!/bin/bash
exec 2>testerror                        ###exec将标准错误输出重定向至testerror文件
echo "Start Now!"
exec 1>testout
echo "this is normal."
echo "this is error." >&2               ###将此输出重定向至stderr


# ./cdx002.sh
Start Now!

# cat testout
this is normal.

# cat testerror                         
this is error.                      

&&&    重定向输入 0< file

这种重定向只要在脚本需要输入时,就会生效。

# cat testfile
this is the ONE
this is the TWO
this is the THREE

# cat cdx003.sh
#!/bin/bash
exec 0<testfile

while read hang
do
  echo "HANG: $hang"
done

# ./cdx003.sh
Line: this is the first ONE
Line: this is the second TWO
Line: this is the third THREE

@@@    创建自己的重定向3~8

&&&    创建输出文件描述符

exec 3>file     exec 3>>file  文件描述符3重定向至file文件。方法与标准1,2类似。

①重定向文件描述符

vim cdx003.sh
#!b/bin/bash
exec 3>&1                                    ###文件描述符3重定向到屏幕输出
exec 1>testout                               ###标准输出重定向到testout文件
echo "Hellow 3 > 1 > testout ."
echo "Hellow 333." >&3                       ###本句输出重定向到文件描述符3的位置
exec 1>&3                                 ###重新将标准输出定向到文件描述符3的现在位置(屏幕)
echo "Hellow Bboy."


# ./cdx003.sh
Hellow 333.
Hellow Bboy.

# cat testout
Hellow 3 > 1 > testout .

②输入与输出类似

exec 6<&0
exec 0<testfile
commond   #重定向到testout文件
exec 0>&6

③创建读写文件描述符

exec 3<>file   

书上的原文:
    这个例子用了exec命令将文件描述符3分配给文件testfile以进行文件读写。接下来,它通过分配好的文件描述符,使用read命令读取文件中的第一行,然后将这一行显示在STDOUT上。最后,它用echo语句将一行数据写入由同一个文件描述符打开的文件中。
    在运行脚本时,一开始还算正常。输出内容表明脚本读取了testfile文件中的第一行。但如果你在脚本运行完毕后,查看testfile文件内容的话,你会发现写入文件中的数据覆盖了已有的数据。
    当脚本向文件中写入数据时,它会从文件指针所处的位置开始。read命令读取了第一行数据,所以它使得文件指针指向了第二行数据的第一个字符。在echo语句将数据输出到文件时,它会将数据放在文件指针的当前位置,覆盖了该位置的已有数据。

老实说这个例子我看的似懂非懂,不知道是我理解能力太差,还是这个例子举得不好。这个例子我就不给大家说明了。

# vim cdx004.sh
#!/bin/bash
exec 3<>testfile                     ###创建文件描述符3和testfile的关联
read line <&3                        
echo “Read: $line"                   
echo "this is error" >&3

# cat testfile
this is the first line
this is the second line
this is the third line

$./cdx004.sh
Read: this is the first line

$cat testfile
this is the first line                        
this is error
cond line
this is the third line

④关闭文件描述符  

vim cdx005.sh
#!/bin/bash
# testing closing file descriptors
exec 3> testfile
echo "This is a test line of data" >&3
exec 3>&-
echo "This won't work" >&3

# ./cdx005.sh
./cdx005.sh: line 6: 3: Bad file descriptor   ###因exec 3>&-关闭了文件描述符,所以最后报错

# cat testfile
This is a test line of data

 

@@@    列出打开的文件描述符 lsof

    lsof命令会列出整个linux系统打开的所有文件描述符。你可以使用选项-p,-d,-a用来过滤输出。-p指定进程ID(-p $$ 显示当前进程ID);-d 指定要显示的文件描述符;-a选项用来对其他两个选项的结果执行布尔AND运算(会使输出结果变得更加简洁)。

@@@    阻止命令输出null

/dev/null  Linux系统上null文件的标准位置,重定向到改文件的任何数据都会被丢掉。

cat  /dev/null  > logfile   清除日志的通用方法,不删除文件,只将文件内容清空。

@@@   创建临时文件

        /tmp目录来存放不需要一直保留的文件。在启动时,自动删除/tmp目录的所有文件。mktemp创建临时文件,不用默认的umask的值,属主有读写权。

        使用模板可以创建不同名字的多个文件,在文件末尾加上6个XXXXXX就可以了。mktemp命令会用6个字符码替换6个X,从而保证目录名在文件中是唯一的。

# mktemp test.XXXXXX
test.h47XzR

# mktemp test.XXXXXX
test.wLBSRM

# mktemp test.XXXXXX
test.gjtA5O

# ls -al test*
-rw------- 1 caishu caishu    0  5月 16 22:39 test.gjtA5O
-rw------- 1 caishu caishu    0  5月 16 22:39 test.h47XzR
-rw------- 1 caishu caishu    0  5月 16 22:39 test.wLBSRM

mktemp -t 命令在/tmp目录创建文件,返回的文件带有全路径,可以在linux系统上任何目录下引用该临时文件。

mktemp -d  创建临时目录     也可以用模板 mktemp -d dir.XXXXXX

&&&    记录消息

用tee命令可以一边发送到显示器一边发送到文件

# date | tee file
mondey may 16 23:03
# cat file
mondey may 16 23:03


# date | tee -a file     ###-a选项可以将内容追加到文件,类似>>
mondey may 16 24:00
# cat file
mondey may 16 23:03
mondey may 16 24:00

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值