[Linux Shell学习系列十一]脚本输入处理-2.重定向

D20

在Linux中,总有3个默认的设备文件是打开的,即标准输入stdin(键盘)、标准输出stdout(屏幕)、标准错误stderr(屏幕)。

这三个文件和任何打开的文件,都可以被重定向。

每个打开的文件被指定一个描述符,如stdin、stdout、stderr的文件描述符分别为0、1、2。对于打开的另外的文件,预留了文件描述符3~9。

 

1. 文件重定向

重定向默认只适用于一条命令。后面的命令继续发送到标准输出。

重定向发生在命令执行之前。

注意:之所以推荐使用cat命令读取文件内容,在于cat用于较好地把多个文件连接在一起,或作为Shell命令行提示符中查看文件内容的快速工具。在脚本中不应该使用cat命令来从管道文件到命令,而应该使用重定向。否则将导致额外的进程被创建。

使用标准输入:

#不指定任何参数而执行cat
$ cat
#似乎什么都不做也不显示命令行提示符,其实此时仍在从标准输入即终端进行读取

#此时输入aaa
aaa
aaa
#第一次显示:在标准模式下,终端回显你输入的字符并允许进行简易的编辑(如退格)等,直到按下回车,才把输入的内容发送到应用程序
#第二次显示:cat命令从标准输入读取行,然后显示到标准输出(同样是你的终端)。

#此时按下Ctrl+D:向终端发送文件结束符,此时cat认为标准输入已经关闭,cat停止读取并结束。
#Bash看到cat命令结束,显示Shell命令行提示符。
$

使用输入重定向将一个文件连接到标准输入:

$ cat < list.txt #此时cat命令为list.txt文件打开了一个文件描述符,并通过这个文件描述符读取文件的内容。此时cat的数据源是文件而不是标准输入。
ab dde
ab   dde
abde
333
a

 

重定向采用数字作为先导,数字表示了将要变更的文件描述符。

$ find . -name "a.txt" -exec lsattr {} \; #test和test-bak文件夹下的a.txt只有root用户可以删除
----i--------e-- ./test-bak/a.txt
----i--------e-- ./test/a.txt

$ cat rmtxt.sh 
#!/bin/bash
#202006

if [ $# -lt 1 ]
then
        echo "Usage: `basename $0` DIRECTORY..."
        exit
fi

for dir in $@
do
        find $dir -name "a.txt" -exec rm -f {} \; #找到文件进行删除
done 2>> errors.log #将标准错误重定向到文件
#注意这里应用于done,会将重定向应用于循环内所有标准错误的输出,
#严格的说,是Bash在循环开始前打开了
errors.log文件并将标准错误指向它,当循环结束时关闭了它。运行在循环内的所有命令从Bash继承打开的文件描述符。
$ ./rmtxt.sh a.txt #执行脚本,标准错误不输出到屏幕 

$
cat errors.log #查看文件
rm: cannot remove ./test-bak/a.txt: Operation not permitted
rm: cannot remove ./test/a.txt: Operation not permitted
#注意:由于使用>,每次循环开始前都会清空文件,因此执行多次后也只有最后一次的

如果不想文件在每次循环之前被清空?

可以使用双重重定向操作符>>。>>将不会清空文件,只是添加新的内容到文件末尾。

 

注意:

1)当一个应用程序需要文件数据且它的创建是为从标准输入读取数据时,使用重定向是一个好主意。而将cat的输出管道到进程是糟糕的办法。

2)当设计一个从不同源头获取数据的应用程序时,最好让你的应用程序从标准输入读取数据。这样,用户就可以使用重定向来获取他想要的数据。

 

2. 从文件输入

 

[Linux Shell学习系列十一]脚本输入处理-2.重定向

上一篇:干掉这碗“交换鸡汤” 恶补H3C和Cisco交换机MSTP对接知识!


下一篇:ubuntu18.04开机显示详细信息