常用shell命令(二)

 


标准文件描述符
STDIN
许多bash命令能接受STDIN的输入,尤其是没有在命令行上指定文件的话。
下面是个用cat 命令处理STDIN输入的数据的例子。
当在命令行上只输入cat命令时,它会从STDIN接受输入。输入一行,cat命令就会显示出一行。
$ cat
this is a test
this is a test
this is a second test.
this is a second test.

 

但你也可以通过STDIN重定向符号强制cat命令接受来自另一个非STDIN文件的输入。
$ cat < testfile
This is the first line.
This is the second line.
This is the third line.
$
STDOUT

 

通过输出重定向符号,通常会显示到显示器的所有输出会被shell重定向到指定的重定向文件。
你也可以将数据追加到某个文件。这可以用>>符号来完成。
$ ls -l > test2
$ cat test2
total 20
-rw-rw-r-- 1 rich rich 53 2014-10-16 11:30 test
-rw-rw-r-- 1 rich rich 0 2014-10-16 11:32 test2
-rw-rw-r-- 1 rich rich 73 2014-10-16 11:23 testfile
$
$ who >> test2
$ cat test2
total 20
-rw-rw-r-- 1 rich rich 53 2014-10-16 11:30 test
-rw-rw-r-- 1 rich rich 0 2014-10-16 11:32 test2
-rw-rw-r-- 1 rich rich 73 2014-10-16 11:23 testfile
rich pts/0 2014-10-17 15:34 (192.168.1.2)
$

 

who命令生成的输出会被追加到test2文件中已有数据的后面。
但是,如果你对脚本使用了标准输出重定向,你会遇到一个问题。下面的例子说明了可能会
出现什么情况。
$ ls -al badfile > test3
ls: cannot access badfile: No such file or directory
$ cat test3
$

 

当命令生成错误消息时,shell并未将错误消息重定向到输出重定向文件。
shell创建了输出重 定向文件,但错误消息却显示在了显示器屏幕上。
注意,在显示test3文件的内容时并没有任何错 误。test3文件创建成功了,只是里面是空的。
shell对于错误消息的处理是跟普通输出分开的。
如果你创建了在后台模式下运行的shell脚 本,通常你必须依赖发送到日志文件的输出消息。
用这种方法的话,如果出现了错误信息,这些 信息是不会出现在日志文件中的。你需要换种方法来处理。
STDERR
shell通过特殊的STDERR文件描述符来处理错误消息。STDERR文件描述符代表shell的标准错 误输出。shell或shell中运行的程序和脚本出错时生成的错误消息都会发送到这个位置。
默认情况下,STDERR文件描述符会和STDOUT文件描述符指向同样的地方(尽管分配给它们 的文件描述符值不同)。也就是说,默认情况下,错误消息也会输出到显示器输出中。
但从上面的例子可以看出,STDERR并不会随着STDOUT的重定向而发生改变。使用脚本时, 你常常会想改变这种行为,尤其是当你希望将错误消息保存到日志文件中的时候。
只重定向错误
$ ls -al badfile 2> test4
$ cat test4
ls: cannot access badfile: No such file or directory
$

 

现在运行该命令,错误消息不会出现在屏幕上了。该命令生成的任何错误消息都会保存在输 出文件中。用这种方法,shell会只重定向错误消息,而非普通数据。
ls命令的正常STDOUT输出仍然会发送到默认的STDOUT文件描述符,也就是显示器。
由于该 命令将文件描述符2的输出(STDERR)重定向到了一个输出文件,shell会将生成的所有错误消息 直接发送到指定的重定向文件中。
$ ls -al test badtest test2 2> test5
-rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2
$ cat test5
ls: cannot access test: No such file or directory
ls: cannot access badtest: No such file or directory
$

 

重定向错误和数据
如果想重定向错误和正常输出,必须用两个重定向符号。需要在符号前面放上待重定向数据 所对应的文件描述符,然后指向用于保存数据的输出文件。
$ ls -al test test2 test3 badtest 2> test6 1> test7
$ cat test6
ls: cannot access test: No such file or directory
ls: cannot access badtest: No such file or directory
$ cat test7
-rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2
-rw-rw-r-- 1 rich rich   0 2014-10-16 11:33 test3
$

 

shell利用1>符号将ls命令的正常输出重定向到了test7文件,而这些输出本该是进入STDOUT 的。所有本该输出到STDERR的错误消息通过2>符号被重定向到了test6文件。
可以用这种方法将脚本的正常输出和脚本生成的错误消息分离开来。这样就可以轻松地识别 出错误信息,再不用在成千上万行正常输出数据中翻腾了。
另外,如果愿意,也可以将STDERR和STDOUT的输出重定向到同一个输出文件。为此bash shell 提供了特殊的重定向符号&>。
$ ls -al test test2 test3 badtest &> test7
$ cat test7
ls: cannot access test: No such file or directory
ls: cannot access badtest: No such file or directory
-rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2
-rw-rw-r-- 1 rich rich   0 2014-10-16 11:33 test3
$

 

当使用&>符时,命令生成的所有输出都会发送到同一位置,包括数据和错误。你会注意到其 中一条错误消息出现的位置和预想中的不一样。badtest文件(列出的最后一个文件)的这条错误 消息出现在输出文件中的第二行。
永久重定向
$ cat test8
#!/bin/bash
# testing STDERR messages
echo "This is an error" >&2
echo "This is normal output"
$
$ ./test8
This is an error
This is normal output
$
$ ./test8 2> test9
This is normal output
$ cat test9
This is an error
$
$ cat test10
#!/bin/bash
# redirecting all output to a file
exec 1>testout
echo "This is a test of redirecting all output"
echo "from a script to another file."
echo "without having to redirect every individual line"
$ ./test10
$ cat testout
This is a test of redirecting all output
from a script to another file.
without having to redirect every individual line
$
$ cat test11
#!/bin/bash
# redirecting output to different locations
exec 2>testerror
echo "This is the start of the script"
echo "now redirecting all output to another location"
exec 1>testout
echo "This output should go to the testout file"
echo "but this should go to the testerror file" >&2
$
$ ./test11
This is the start of the script
now redirecting all output to another location
$ cat testout
This output should go to the testout file
$ cat testerror
but this should go to the testerror file
$
$ cat test12
#!/bin/bash
# redirecting file input
exec 0< testfile
count=1
while read line
do
echo "Line #$count: $line"
count=$[ $count + 1 ]
done
$ ./test12
Line #1: This is the first line.
Line #2: This is the second line.
Line #3: This is the third line.
$
 

 

 
 
 
 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

posted @ 2020-08-19 10:31  anobscureretreat  阅读(211)  评论(0编辑  收藏  举报