shell脚本编程-重定向

简介:

计算机最基础的功能是可以提供输入输出操作,常见的输入设备有键盘、鼠标、扫描仪等,对于Linux系统来说,通常以键盘为默认输入设备,又称标准输入设备;

计算机常见的输出设备有显示器、蜂鸣器、打印机等,而Linux系统则以显示器为默认输出设备,又称标准输出设备。

所谓”重定向“,就是将原本应该从标准输入设备(键盘)输入的数据,改由其他文件或设备输入;或将原本应该输出到标准输出设备(显示器)的内容,改而输出到其他文件或设备上.

系统在启动一个进程的同时会为该进程打开三个文件:标准输入(stdin)、标准输出(stdout)、标准错误输出(stderr),分别用文件标识符0、1、2来标识.默认情况下分别为,键盘,显示器,显示器.

 一、I/O重定向

 二、使用exec

 三、Here Document

一、I/O重定向

  I/O重定向可以将任何文件、命令、脚本、程序或脚本的输出重定向到另外一个文件、命令、程序或脚本.

> 标准输出覆盖重定向:将命令的输出重定向输出到其他文件中
>> 标准输出追加重定向:将命令的输出重定向输出到其他文件中,同时会覆盖文件中的已有的内容
>& 标准输出重定向:将一个标识的输出重定向到另一个标识的输入
< 标准输入重定向:命令将从指定文件中读取输入而不是从键盘输入
| 管道:从一个命令中读取输出并作为另一个命令的输入.

 

 

 

 

 

 

   1.标准输出覆盖重定向:>

  使用标准重定向符号可以将原来输出到显示器上的内容重定向到一个文件中

[rhat@localhost ~]$ ls -l
total 36
drwxr-xr-x. 3 rhat rhat 4096 Sep 27 06:30 Desktop
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Documents
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Downloads
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Music
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Pictures
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Public
drwxrwxr-x. 2 rhat rhat 4096 Sep 27 03:08 shell
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Templates
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Videos
[rhat@localhost ~]$ ls -l > ls_rhat.txt
[rhat@localhost ~]$ cat ls_rhat.txt 
total 36
drwxr-xr-x. 3 rhat rhat 4096 Sep 27 06:30 Desktop
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Documents
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Downloads
-rw-rw-r--. 1 rhat rhat    0 Sep 28 02:21 ls_rhat.txt
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Music
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Pictures
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Public
drwxrwxr-x. 2 rhat rhat 4096 Sep 27 03:08 shell
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Templates
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Videos

   如果文件不存在就会创建一个,存在且内容不为空,会删除原来内容然后再写,所以有时候需要判断原文件是否存在.下面查看一个不存在的文件:

[rhat@localhost ~]$ ls -l /usr/noExist > ls_NoExist.txt #也可写成 ls -l /usr/noExist 1> ls_NOExist.txt ,他两是等效的.
ls: cannot access /usr/noExist: No such file or directory
[rhat@localhost ~]$ cat ls_NoExist.txt 
#会发现什么也没有,
#因为>默认重定向的是标准输出(1)
#这次确实标准错误却是错误输出,所以应该写成 2>
#eg:
[rhat@localhost ~]$ ls -l /usr/noExist 2> ls_NoExist.txt
[rhat@localhost ~]$ cat ls_NoExist.txt 
ls: cannot access /usr/noExist: No such file or directory

  如果某命令既有标准输出,又有标准错误输出,可以分别指派不同的标识符到不同的文件中:

[rhat@localhost ~]$ COMMAND 1> stdout.txt 2> stderr.txt

   2.标注输出追加重定向:>>

    ">>" 用法和 ">" 完全一致,不同的只是如果指定的重定向文件存在且不为空,重定向并不会清空源文件内容,而是将命令的输出新增到源文件尾部。如下:

[rhat@localhost ~]$ ls -l /usr/ >> ls_rhat.txt 
[rhat@localhost ~]$ cat ls_rhat.txt 
total 40
drwxr-xr-x. 3 rhat rhat 4096 Sep 27 06:30 Desktop
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Documents
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Downloads
-rw-rw-r--. 1 rhat rhat   58 Sep 28 02:26 ls_NoExist.txt
-rw-rw-r--. 1 rhat rhat    0 Sep 28 02:36 ls_rhat.txt
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Music
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Pictures
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Public
drwxrwxr-x. 2 rhat rhat 4096 Sep 27 03:08 shell
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Templates
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Videos
total 144
dr-xr-xr-x.   2 root root 45056 Sep 26 04:41 bin
drwxr-xr-x.   2 root root  4096 Jun 28  2011 etc
drwxr-xr-x.   2 root root  4096 Jun 28  2011 games
drwxr-xr-x.  32 root root  4096 Sep 26 06:27 include
dr-xr-xr-x.  15 root root  4096 Sep 26 06:32 lib
dr-xr-xr-x.  88 root root 40960 Sep 26 04:41 lib64
drwxr-xr-x.  22 root root 12288 Sep 26 04:41 libexec
drwxr-xr-x.  14 root root  4096 Sep 27 06:23 local
dr-xr-xr-x.   2 root root 12288 Sep 26 04:41 sbin
drwxr-xr-x. 171 root root  4096 Sep 26 06:29 share
drwxr-xr-x.   4 root root  4096 Sep 26 06:25 src
lrwxrwxrwx.   1 root root    10 Sep 26 06:25 tmp -> ../var/tmp

   3.标识输出重定向:>&

    标识重定向的作用是将一个标识的输出重定向到另一个标识的输入,比如想将标准输出和标准错误同时输出到同一个文件:

[rhat@localhost ~]$ COMMAND > stdout_stderr.txt 2>&1

     以上表示将标准输出到stdout_stderr.txt,如果有标准错误输出也同时重定向到该文件中.

    eg:

[rhat@localhost home]$ find / -type f -name *.txt
find: `/var/cache/hald': Permission denied
/usr/lib64/python2.6/site-packages/simplejson-2.0.9-py2.6.egg-info/top_level.txt
/usr/lib64/python2.6/site-packages/simplejson-2.0.9-py2.6.egg-info/dependency_links.txt
/usr/lib64/python2.6/site-packages/rhsm-1.1.8-py2.6.egg-info/SOURCES.txt
....
/usr/share/doc/ivtv-firmware-20080701/license-end-user.txt
/usr/share/doc/ivtv-firmware-20080701/license-oemihvisv.txt
/usr/share/doc/obexd-0.19/client-api.txt

     以上包含错误输出也包含标准输出,可以用如下的方式来进行分离:

[rhat@localhost home]$ find / -type f -name *.txt > std_out.txt 2> stderr.txt 

     当然错误输出可能并不关心,我们可以将标准错误输出到/dev/null 中,系统会将任何输出到该设备的内容全部删除.

   4.标准输入重定向:<

    标准输入重定向将原本应从标准输入设备中读取的内容转由文件内容输入,也就是将文件内容写入标准输入中.例如:

[rhat@localhost ~]$ vim fruit01.txt
banana
apple
carrot
[rhat@localhost ~]$ sort < fruit01.txt #是linux中一个排序的命令.
apple
banana
carrot

   5.管道:|

    管道也是一种重要的I/O重定向方法,就是将一个命令的输出作为另一个命令的输入,例如:

[rhat@localhost ~]$ cat fruit01.txt 
banana
apple
carrot
[rhat@localhost ~]$ cat fruit01.txt | sort   #cat命令的输出冲顶想到sort命令中
apple
banana
carrot

二、使用exec

  exec是Shell的内建命令,执行这个命令时系统不会启动新的Shell,而是用要被执行的命令替换当前的Shell进程.下表为exec的用法.

exec <file 将file文件中的内容作为exec的标准输入
exec >file 将file文件作为标准输出
exec 3<file 指定文件标识符
exec 3<&- 关闭文件标识符
exec 3>file 将写入指定文件标识符的内容写入指定文件(这里的文件是file)
exec 4<&3 创建文件标识符3的拷贝4

 

 

 

 

 

 

  1.将file文件中的内容作为exec的标准输入.

    系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变.所以exec并不会创建新的进程.只是替换了原来进程上下文的内容.

[rhat@localhost ~]$ bash  #开启一个新的Shell,不启动新的shell,根shell将最终关闭.
[rhat@localhost ~]$ cat command.txt #查看文件中都有哪些命令
echo "Hello , I'am a echo command"
ls -l
[rhat@localhost ~]$ exec <command.txt #将文件作为本shell的标准输入
[rhat@localhost ~]$ echo "Hello , I'am a echo command"  #执行echo
Hello , I'am a echo command
[rhat@localhost ~]$ ls -l  #执行ls -l
total 44
-rw-rw-r--. 1 rhat rhat   41 Sep 28 03:24 command.txt
drwxr-xr-x. 3 rhat rhat 4096 Sep 27 06:30 Desktop
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Documents
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Downloads
-rw-r--r--. 1 rhat rhat   20 Sep 28 03:08 fruit01.txt
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Music
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Pictures
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Public
drwxrwxr-x. 2 rhat rhat 4096 Sep 27 03:08 shell
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Templates
drwxr-xr-x. 2 rhat rhat 4096 Sep 26 00:46 Videos
[rhat@localhost ~]$ exit #文件中的命令执行完毕,退出. 回到上一层shell.
[rhat@localhost ~]$    #根Shell.

  2.将file文件作为标准输出.

    利用exec可将标准输出全部重定向到某个文件中。

[rhat@localhost ~]$ exec >out01.txt              #将shell的标准输出重定向到out01.txt中.
[rhat@localhost ~]$ pwd                    #执行pwd命令 ,因为重定向到out01.txt中,所以看不到输出.
[rhat@localhost ~]$ echo "HelloWorld,I'm a sehll"    #执行echo命令
[rhat@localhost ~]$ exec >/dev/tty             #将标准输出重定向到显示器.
[rhat@localhost ~]$ cat out01.txt              #查看之前两个命令执行的结果.
/home/rhat
HelloWorld,I'm a sehll

  3.指定文件标识符.

    通过exec指定文件标识符,可以通过对该标识符操作进行文件的操作.拿排序为例.

[rhat@localhost ~]$ exec 3<fruit01.txt 
[rhat@localhost ~]$ cat fruit01.txt 
banana
apple
carrot
[rhat@localhost ~]$ sort <&3    #在Linux中,文件标识符也是一种"设备",这个标识符会出现在/dev/fd目录中。进入这个目录,可以看到3是一个到该文件的软连接---:Linux下一切皆文件.
apple
banana
carrot

  4.关闭文件标识符.

  主动打开的问价标识符需要主动关闭,否则除了系统系统重启,该文件标识符会一直被占用.

[rhat@localhost ~]$ exec 3<&-
[rhat@localhost ~]$ ls -l /dev/fd
lrwxrwxrwx. 1 root root 13 Sep 26 00:45 /dev/fd -> /proc/self/fd
[rhat@localhost ~]$ ls -l /proc/self/fd
total 0
lrwx------. 1 rhat rhat 64 Sep 28 03:45 0 -> /dev/pts/0
l-wx------. 1 rhat rhat 64 Sep 28 03:45 1 -> /dev/tty
lrwx------. 1 rhat rhat 64 Sep 28 03:45 2 -> /dev/pts/0
lr-x------. 1 rhat rhat 64 Sep 28 03:45 3 -> /proc/60867/fd

  5.将写入指定文件标识符的内容写入制定文件

#创建文件标识符3,并将写入3的内容全部写入file.txt文件中.
[rhat@localhost ~]$ exec 3>file.txt
#命令的输出内容写到标识符3中.
[rhat@localhost ~]$ echo "Hello , world" >&3
[rhat@localhost ~]$ cat file.txt 
Hello , world

  6.创建文件标识符的拷贝

[rhat@localhost ~]$ exec 3<fruit01.txt 
#创建文件标识符3的拷贝4
[rhat@localhost ~]$ exec 4<&3
#可以看到3和4都指向同一个文件
[rhat@localhost ~]$ ls -l /dev/fd/
total 0
lrwx------. 1 rhat rhat 64 Sep 28 03:54 0 -> /dev/pts/0
l-wx------. 1 rhat rhat 64 Sep 28 03:54 1 -> /dev/tty
lrwx------. 1 rhat rhat 64 Sep 28 03:54 2 -> /dev/pts/0
lr-x------. 1 rhat rhat 64 Sep 28 03:54 3 -> /home/rhat/fruit01.txt
lr-x------. 1 rhat rhat 64 Sep 28 03:54 4 -> /home/rhat/fruit01.txt
lr-x------. 1 rhat rhat 64 Sep 28 03:54 5 -> /proc/61127/fd
[rhat@localhost ~]$ cat /dev/fd/4
banana
apple
carrot

三、Here Document

  Here Document又称为此处文档,用于在命令或脚本中按行输入文本。Here Document的格式为<<delimiter,其中delimiter是一个用于标注"分割符",该分隔符后所有的输入都被当做是输入的文本,直到出现下一个分隔符为止.

  在脚本中收输入如下:

[rhat@localhost ~]$ sort << END
> a
> b
> c
> END
a
b
c
#以文件为例:
[rhat@localhost ~]$ cat >> HelloWord01.txt << END  #>>为追加重定向符号,<<END 为标准输入重定向符号.
> hello
> world
> ni
> hao
> END
[rhat@localhost ~]$ cat HelloWord01.txt 
hello
world
ni
hao

 

返 回 顶 部

posted @ 2015-09-28 19:13  超超xc  Views(499)  Comments(0Edit  收藏  举报
I suppose,were childrenonec.