十二章显示数据
原创
©著作权归作者所有:来自51CTO博客作者oneliting的原创作品,请联系作者获取转载授权,否则将追究法律责任
Key words : 了解输入和输出 标准文件描述 在脚本中重定向输入和输出 创建自己的重定向 命令tee
一、了解输入和输出
我们常见的显示输出方式有两种:
a、直接在屏幕上显示输出 b 、将输出重定向到文件中
这两种方法要么生成全部数据输出,要么没有任何输出。但有时候需要直接在显示屏上显示一部分数据,在文件中显示另一部分数据。在这种情况下,最好能了解Linux处理输入输出的方式,一遍让脚本输出到正确的位置。
标准文件描述
Linux系统将每个对象(包括输入和输出)当作文件处理,并使用文件描述符标识每个文件对象。文件描述符是一个非负整数,可以唯一地标识会话中打开的文件。每个进程最多可以有9个打开文件的描述符。
bash shell 为特殊需要保留了前三个文件描述符:0、1、2 分别代表标准输入、标准输出、标准错误
1、0 : STDIN 标准输入
对于终端接口,标准输入是键盘,shell通过STDIN文件描述符从键盘接受输入。
除了从键盘输入字符,我们还可以使用输入重定向符号 (<)来获取数据,就像通过键盘输入一样。
[root@localhost ~]# cat test
/root/bb
[root@localhost ~]# cat < test
/root/bb
[root@localhost ~]# ll < test
总计 1548
-rw-r--r-- 1 root root 205 07-24 21:04 \
-rwxr--r-- 1 root root 22 07-29 09:24 aa
-rw------- 1 root root 1177 04-09 05:58 anaconda-ks.cfg
drwxr-xr-x 2 root root 4096 07-29 21:30 bb
-rw-r--r-- 1 root root 7336 07-25 05:22 count
-rwxr--r-- 1 root root 65 07-25 22:35 delusers
drwxr-xr-x 4 root root 4096 07-29 00:13 Desktop
。。。。。。
注意: < 只是将test 这个文件名重定向给前面的命令,而没有重定向文件里面的内容,所以ll 命令显示的只是当前目录下的内容而没有显示 /root/bb目录下的内容。
2、1 : SDOUT 标准输出
在终端接口,标准输出是显示器屏幕。当然,可以利用从定向符号 > (覆盖重定向)和 >> (追加重定向)到指定的文件。错误信息除外。
例:覆盖和追加的分别
[root@localhost ~]# cat test
wlt
[root@localhost ~]# echo wzp > test
[root@localhost ~]# cat test
wzp
[root@localhost ~]# echo wlt >> test
[root@localhost ~]# cat test
wzp
wlt
3、 2 :STDERR 标准错误
STDERR 文件描述符和STDOUT文件描述符指向相同的位置,这意味着默认情况下,所有错误信息都显示在显示器上,处理脚本时通常要更改该行为,尤其是需要在日志文件中记录错误消息时。
例:利用文件描述符2 重定向错误
[root@localhost ~]# ls -al notexitfile 2> test
[root@localhost ~]# cat test
ls: notexitfile: 没有那个文件或目录
如果需要同时重定向错误和正常数据,则必须要使用两个重定向符号:
[root@localhost ~]# ls -al notexitfile /tm p 2> errorfile 1> normalfile
[root@localhost ~]# cat errorfile
ls: notexitfile: 没有那个文件或目录
[root@localhost ~]# cat normalfile
/tmp:
总计 672
drwxrwxrwt 61 root root 4096 07-29 21:22 .
drwxr-xr-x 29 root root 4096 07-29 21:18 ..
drwxrwxrwt 2 root root 4096 07-29 21:18 .font-unix
drwx------ 3 root root 4096 07-21 20:31 gconfd-root
-rw------- 1 root root 66 07-19 22:22 .gdm0R2QYV
。。。。。。
还可以把所有的信息都放在一个文件里面: &>
[root@localhost ~]# ls -al notexitfile /tmp &> test
[root@localhost ~]# cat test
ls: notexitfile: 没有那个文件或目录
/tmp:
总计 672
drwxrwxrwt 61 root root 4096 07-29 21:22 .
drwxr-xr-x 29 root root 4096 07-29 21:18 ..
drwxrwxrwt 2 root root 4096 07-29 21:18 .font-unix
drwx------ 3 root root 4096 07-21 20:31 gconfd-root
。。。。。。
二、在脚本中重定向输入和输出
1、在脚本中重定向输入
使用命令exec :exec 0< testfile
这个命令告诉shell从文件testfile而不是STDIN获取输入。
例:
[root@localhost ~]# cat testfile
first line
second line
third line
[root@localhost ~]# cat test
#!/bin/bash
exec 0< testfile
count=1
while read line
do
echo "Line $count : $line"
count=$[ $count + 1 ]
done
[root@localhost ~]# ./test
Line 1 : first line
Line 2 : second line
Line 3 : third line
[root@localhost ~]#
2、使用脚本重定向输出
方式有两种:a、临时重定向每一行 b、永久重定向所有命令
1)、临时重定向
这里搞懂一个问题:重定向到某个文件描述符时,必须在该文件描述符前面加&号
[root@localhost ~]# cat test
#!/bin/bash
echo "this is an error" >&2
echo "this is normal output"
[root@localhost ~]# ./test
this is an error
this is normal output
这个脚本运行的时候没什么异常,因为重定向到错误文件描述符的内容默认也是从屏幕输出
但再次允许脚本并把标准输出重定向到normalfile文件时发现只剩下标准错误信息输出。
[root@localhost ~]# ./test 1> normalfile
this is an error
[root@localhost ~]# cat normalfile
this is normal output
2)、永久重定向
使用exec命令可以通知shell在执行脚本时重定向特定的文件描述符:
例:
[root@localhost ~]# cat test
#!/bin/bash
exec 1> testout 把所有标准输出重定向到testout文件
exec 2> testerr 把所有错误输出重定向到testerr文件
date
date "%F %D %M"
cat /root/notexitfile
echo "do you understand?"
[root@localhost ~]# cat testout
2011年 07月 29日 星期五 22:30:49 EDT
do you understand?
[root@localhost ~]# cat testerr
date: invalid date “%F %D %M”
cat: /root/notexitfile: 没有那个文件或目录
三、创建自己的重定向
在脚本中重定向输入和输出时并不局限于3种默认的文件描述符,shell中最多可以有9个打开的文件描述符,其他6个3~8可以应用到任何文件然后在脚本中使用。
1、创建输出文件描述符
使用exec命令
例:
[root@localhost ~]# cat test
#!/bin/bash
exec 3>testout 创建了文件描述符3
echo "this should display on the monitor"
echo "this should be stored in the file" >&3 重定向到文件描述符3
echo "this should be back on the monitor"
[root@localhost ~]# ./test
this should display on the monitor
this should be back on the monitor
[root@localhost ~]# cat testout
this should be stored in the file
这样就可以将普通信息输出到monitor ,将特殊信息输出到指定文件了。
2、重定向文件描述符
例:
[root@localhost ~]# cat testout
this should store in the testout file
along with this line
[root@localhost ~]# cat test
#!/bin/bash
exec 3>&1 把文件描述符3重定向到1,就是STDOUT,也就是任何发送到文件描述符3
的输出都将显示在monitor上
exec 1>testout 把STDOUT重定向到testout文件
echo "this should store in the testout file"
echo "along with this line"
exec 1>&3 把下面的STDOUT重定向到文件描述符3,而3已经被重定向了1,所以还是输出
到monitor
echo "now things should be back to normal"
[root@localhost ~]# ./test
now things should be back to normal
[root@localhost ~]# cat testout
this should store in the testout file
along with this line
3、创建输入文件描述符
例:
[root@localhost ~]# cat testfile
first line
second line
third line
[root@localhost ~]# cat test
#!/bin/bash
exec 6<&0 使用文件描述符6保留STDIN的位置
exec 0<testfile 将STDIN重定向到文件
count=1
while read line
do
echo "Line $count : $line"
count=$[ $count + 1 ]
done
exec 0<&6 读完所有行后再将STDIN设回原来的位置使read命令能正常得到键盘输入
read -p "Are you done now?" answer
case $answer in
Y|y ) echo "Goddbey";;
N|n ) echo "sorry,this is the end";;
esac
[root@localhost ~]# ./test
Line 1 : first line
Line 2 : second line
Line 3 : third line
Are you done now?y
Goddbey
4、关闭文件描述符
关闭文件描述符,只需将它重定向到特殊符号 :&-
[root@localhost ~]# cat test
#!/bin/bash
exec 3>&1
echo "this is a test line of data" >&3
exec 3>&- 这条命令前的描述符3是可用的。
echo "again ,test" >&3
[root@localhost ~]# ./test
this is a test line of data
./test: line 5: 3: 错误的文件描述符
5、列出开放的文件描述符
有时候需要跟踪那个文件描述符重定向到了哪个位置。bash shell提供了lsof命令来列出整个Linux系统上所有开放的文件描述符。但这是个有争议的功能,因为它会向非系统管理员提供有关系统的信息,所以有些Linux系统会隐藏该命令。要使用普通用户帐号允许这个命令,必须使用完全路径名。
[root@localhost ~]# /usr/sbin/lsof
该命令会产生大量的输出,显示Linux系统上当前开放的每个文件的相关信息,包括所有后台运行的进程、登录到系统的用户账户。
常用参数:
-p : 指定进程ID
-d :指定要显示的文件描述符编号
$$ : 特殊环境变量,确定进程的当前PID
例;
[root@localhost ~]# cat test
#!/bin/bash
exec 6<testfile
exec 3>&1
echo "this is a test line of data" >&3
/usr/sbin/lsof -a -p $$ -d0,1,2,3,4,5,6
[root@localhost ~]# ./test
this is a test line of data
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
test 6561 root 0u CHR 136,0 2 /dev/pts/0
test 6561 root 1u CHR 136,0 2 /dev/pts/0
test 6561 root 2u CHR 136,0 2 /dev/pts/0
test 6561 root 3u CHR 136,0 2 /dev/pts/0
test 6561 root 6r REG 253,0 37 2590456 /root/testfile
COMMAND:进程中命令名称的前九个字符
FD:文件描述符编号和访问类型(r:读取;w-写入;u-读取/写入)
TYPE :字符类型(CHR:字符、BLK:块、DIR:目录、REG:常规文件)
SIZE:如果可用则为文件大小
SIZE:文件节点编号
6、禁止命令输出
用黑洞文件: /dev/null
例
[root@localhost ~]# ls -a > /dev/null 禁止输出
[root@localhost ~]# cat /dev/null > testfile 清空文件
[root@localhost ~]# cat testfile
7、命令tee
有时候需要把输出同时发送到monitor和指定文件,这时不用做两次重定向,只需使用tee命令
例:
[root@localhost ~]# date | tee testfile
2011年 07月 30日 星期六 09:29:13 EDT
[root@localhost ~]# cat testfile
2011年 07月 30日 星期六 09:29:13 EDT
注意:tee命令会覆盖输出文件,需要追加内容时需要加 -a参数
[root@localhost ~]# who | tee -a testfile
root :0 2011-07-30 07:22
root pts/0 2011-07-30 07:23 (:0.0)
[root@localhost ~]# cat testfile
2011年 07月 30日 星期六 09:29:13 EDT
root :0 2011-07-30 07:22
root pts/0 2011-07-30 07:23 (:0.0)
上一篇:第十一章 处理用户输入
下一篇:十三章脚本控制
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
谷歌地球引擎:导入、筛选、显示栅格遥感影像数据
本文介绍谷歌地球引擎GEE自带的各类遥感、高程等栅格数据导入,并进行可视化显示的方法。本文是谷歌地球引擎(Google Earth Engine,GEE)系列教学文章的第二篇~
GEE 谷歌地球引擎 Earth Engine 遥感影像 GIS数据 -
第十二章 - 执行引擎
第十二章 - 执行引擎文章目录第十二章 - 执行引擎1.执行引擎概述1.1 执行引擎的工作流程2.Java代码编可以设置
java 开发语言 后端 编译器 字节码 -
第十二章 映射 Map
第十二章 映射 MapMap 在有些编程语言中也叫做字典(dictionary,比如 Python、Objective-C
数据结构 红黑树 Map TreeMap 链表 -
第十二章编程作业
1). 编程实现:将网络上一张图片或一个mp3或一个视频的信息保存到本地。代码:packag
网络 socket java udp .net