呈现数据
- 显示脚本输出的方法:
- 在显示器屏幕上显示输出
- 将输出重定向到文件中
标准文件描述符:
linux用文件描述符来标识每个文件对象。文件描述符是一个非负整数,可以唯一的标识会话中打开的文件。每一个过程一次最多可以有9个文件
描述符。处于特殊目的,shell保留了最早的3个文件描述符(0 1 2 )
文件描述符 缩写
0 stdin
1 stdout
2 stderr
1.stdin
stdin 文件描述符代表shell的标准输入。对终端界面来说,标准输入是键盘shell 从STDIN 文件描述符对应的键盘获得输入,在用户输入时处理每个字符。
在使用输入重定向符号< 时,linux会用重定向指定的文件来替换标准输入文件描述符。它会读取文件并提取数据,就如同他是键盘上键入的。
许多bash命令能接受STDIN的输入,尤其是没有在命令行上指定文件的话。
下面是用cat 处理STDIN输入的数据的例子:
[root@zw-test-db ~]# cat test
this is a apple
this is a book
go for a walk
[root@zw-test-db ~]# cat < test
this is a apple
this is a book
go for a walk
现在cat命令会用test文件中的行作为输入。你可以使用这种技术来向任何能从STDIN接受数据的shell命令输入数据
STDOUT
STDOUT文件描述符代表标准的shell输出,在终端界面行,标准输出就是终端显示器。默认的情况,很多bash命令会定向输出到STDOUT文件描述符。
[root@zw-test-db ~]# ls -l > bb
[root@zw-test-db ~]# cat bb
total 304856
-rw-r--r-- 1 root root 2 Jul 1 11:42 ?
-rw-------. 1 root root 1356 Oct 9 2015 anaconda-ks.cfg
-rw-r--r-- 1 root root 173 Jul 1 15:25 badtest
-rw-r--r-- 1 root root 0 Jul 12 16:46 bb
drwxr-xr-x. 2 root root 4096 Jul 6 14:14 Desktop
drwxr-xr-x. 2 root root 4096 Oct 9 2015 Documents
drwxr-xr-x. 2 root root 4096 Oct 9 2015 Downloads
-rwxr-xr-x. 1 root root 941 Oct 12 2015 eth0.sh
-rw-r--r-- 1 root root 63 Jul 1 11:28 if.s
-rw-r--r-- 1 root root 1937 Jul 6 15:52 installmysql
-rw-r--r-- 1 root root 32 Jul 1 17:12 logfile
-rw-r--r-- 1 root root 144 Jul 11 11:15 log.log
drwxr-xr-x. 2 root root 4096 Oct 9 2015 Music
-rw-r--r-- 1 root root 311771412 Jul 6 15:28 mysql-5.6.23-linux-glibc2.5-x86_64.tar.gz
[root@zw-test-db ~]# cat bb|more
total 304856
-rw-r--r-- 1 root root 2 Jul 1 11:42 ?
-rw-------. 1 root root 1356 Oct 9 2015 anaconda-ks.cfg
-rw-r--r-- 1 root root 173 Jul 1 15:25 badtest
-rw-r--r-- 1 root root 0 Jul 12 16:46 bb
drwxr-xr-x. 2 root root 4096 Jul 6 14:14 Desktop
drwxr-xr-x. 2 root root 4096 Oct 9 2015 Documents
drwxr-xr-x. 2 root root 4096 Oct 9 2015 Downloads
-rwxr-xr-x. 1 root root 941 Oct 12 2015 eth0.sh
-rw-r--r-- 1 root root 63 Jul 1 11:28 if.s
-rw-r--r-- 1 root root 1937 Jul 6 15:52 installmysql
-rw-r--r-- 1 root root 32 Jul 1 17:12 logfile
-rw-r--r-- 1 root root 144 Jul 11 11:15 log.log
drwxr-xr-x. 2 root root 4096 Oct 9 2015 Music
-rw-r--r-- 1 root root 311771412 Jul 6 15:28 mysql-5.6.23-linux-glibc2.5-x86_64.tar.gz
通过输出重定向符号,通常会显示到显示器的所有输出会被shell重定向到指定的重定向空间。你也可以将数据追加到某个文件。可以用>>符号完成
[root@zw-test-db ~]# who >> bb
[root@zw-test-db ~]# cat bb
total 304856
-rw-r--r-- 1 root root 2 Jul 1 11:42 ?
-rw-------. 1 root root 1356 Oct 9 2015 anaconda-ks.cfg
-rw-r--r-- 1 root root 173 Jul 1 15:25 badtest
-rw-r--r-- 1 root root 0 Jul 12 16:46 bb
drwxr-xr-x. 2 root root 4096 Jul 6 14:14 Desktop
drwxr-xr-x. 2 root root 4096 Oct 9 2015 Documents
......
root pts/0 2016-07-12 09:55 (192.168.23.82)
[root@zw-test-db ~]# ls 0as > bbb
ls: cannot access 0as: No such file or directory
[root@zw-test-db ~]# cat bbb
如果有错误信息,不会被保存到bbb文件。如果想保存到文件,需要换种方式处理:
STDERR
shell 通过特殊的STDERR文件描述符来处理错误消息。
重定向错误:
1.只重定向错误
[root@zw-test-db ~]# ls -al test2 test1 2>log1.log
-rw-r--r-- 1 root root 70 Jul 1 11:32 test2
[root@zw-test-db ~]# cat log1.log
ls: cannot access test1: No such file or directory
ls的正常STDOUT输出仍然会发送到默认的STDOUT文件描述符,也就是显示器。由于该命令重定向了文件描述符2的输出
到了一个输出文件,shell将会生成的任何错误的消息直接发送到指定的重定向文件中。
2.重定向错误和数据
如果你想重定向错误和正常输出,你必须用两个重定向符号。
[root@zw-test-db ~]# ls -al test2 test1 2>log2.log test7 1>log3.log
[root@zw-test-db ~]# cat log2.log
ls: cannot access test1: No such file or directory
[root@zw-test-db ~]# cat log3.log
-rw-r--r-- 1 root root 70 Jul 1 11:32 test2
-rw-r--r-- 1 root root 155 Jul 1 15:02 test7
shell 用 1>符号将ls命令的本该输出到STDOUT的正常输出重定向到了log3文件,错误消息被重定向到啦log2文件
如果你愿意,可以将STDERR和STDOUT的输出重定向到同一个输出文件。为此shell提供了特殊的重定向符号&>:
[root@zw-test-db ~]# ls -al test2 test1 test7 &>log4.log
[root@zw-test-db ~]# cat log4.log
ls: cannot access test1: No such file or directory
-rw-r--r-- 1 root root 70 Jul 1 11:32 test2
-rw-r--r-- 1 root root 155 Jul 1 15:02 test7
当使用&>符号时,命令生成的所有输出都会发送到同一位置,包括数据和错误
3.在脚本中重定向输出
你可以在脚本中用STDOUT和STDERR文件描述符来在多个位置生成输出
只要简单的重定向相应的文件描述符。有两种方法在脚本中重定向输出:
临时重定向每行输出
永久重定向脚本中的所有命令
4.临时重定向:
如果你要故意在脚本中生成错误信息,可以单独每一行输出重定向到STDERR,
你所需要做的是吃用重定向符将输出重定向到STDERR文件描述符。在重定向到文件
描述符时,你必须在文件描述符数字前极爱一个and符&
echo "this is an error message" >&2
[root@zw-test-db ~]# echo "this is an error message" >&2
this is an error message
[root@zw-test-db ~]#
[root@zw-test-db ~]#vim test78
#!/bin/bash
# testing STDERR message
echo "This is an error " >&2
echo "this is normal output"
[root@zw-test-db ~]# sh test78
This is an error
this is normal output
如果你在运行脚本时重定向了STDERR,脚本中所偶有定向到STDERR的文本都会被重定向
[root@zw-test-db ~]# sh test78 2>log4.log
this is normal output
[root@zw-test-db ~]# cat log4.log
This is an error
正确信息打印出来了,错误信息重定向到log4.log 文件里面
5.永久重定向
如果脚本中有大量数据需要重定向,那么会很繁琐你可以用 exec 命令告诉shell在脚本执行期间重定向某个特定的文件描述符号
vim test79
#!/bin/bash
# redirecting all output to a file
exec 1>log5.log
echo "this is a test of redirecting all output"
echo "from a scriipt to antoher file"
echo "whithcout having to redirect every individual"
[root@zw-test-db ~]# sh test79
[root@zw-test-db ~]# cat log5.log
this is a test of redirecting all output
from a scriipt to antoher file
whithcout having to redirect every individual
exec 命令会启动一个新shell并将STDOUT文件描述符重定向到文件,脚本中发给STDOUT的所有输出会被重定向到文件
[root@zw-test-db ~]# vim test80
#!/bin/bash
# redirecting output to differect location
exec 2>log6.log
echo "this is the start of the script"
echo "now redirecting all output to another location"
exec 1>log7.log
echo "this output should go to the testout file"
echo "but this should go the testerror file" >&2
[root@zw-test-db ~]# sh test80
this is the start of the script
now redirecting all output to another location
[root@zw-test-db ~]# cat log6.log
but this should go the testerror file
[root@zw-test-db ~]# cat log7.log
this output should go to the testout file
6.在脚本中重定向输入
你可以使用在脚本中用STDOUT 和 STDERR 的同样方法来将STDIN从键盘重定向到其他位置。exec命令允许你将STDIN重定向到linux系统上的文件中
exec 0< log8.log
这个命令告诉shell它应该从文件log8.log中获得输入,而不是 STDIN。这个重定向只要在脚本需要输入时就会用
[root@zw-test-db ~]# vim test81
#!/bin/bash
#! redirecting file input
exec 0< log6.log
count=1
while read line
do
echo "Line #$count:$line"
count=$[ $count+1 ]
done
[root@zw-test-db ~]# sh test81
Line #1:this is first line
Line #2:this is second line
Line #3:this is third line