shell脚本编程-重定向
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
shell脚本编程-重定向
简介:
计算机最基础的功能是可以提供输⼊输出操作,常见的输⼊设备有键盘、⿏标、扫描仪等,对于Linux系统来说,通常以键盘为默认输⼊设备,⼜称标准输⼊设备;
计算机常见的输出设备有显⽰器、蜂鸣器、打印机等,⽽Linux系统则以显⽰器为默认输出设备,⼜称标准输出设备。
所谓”重定向“,就是将原本应该从标准输⼊设备(键盘)输⼊的数据,改由其他⽂件或设备输⼊;或将原本应该输出到标准输出设备(显⽰器)的内容,改⽽输出到其他⽂件或设备上.
系统在启动⼀个进程的同时会为该进程打开三个⽂件:标准输⼊(stdin)、标准输出(stdout)、标准错误输出(stderr),分别⽤⽂件标识符0、1、2来标识.默认情况下分别为,键盘,显⽰器,显⽰器.
⼀、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 ~]$ exec3<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 ~]$ exec3<fruit01.txt
#创建⽂件标识符3的拷贝4
[rhat@localhost ~]$ exec4<&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。