shell基础(四)

四.shell的数据流重定向,管道,here文档,命令列表

4.1shell的数据流重定向
程序就像是一个黑盒子,将原始数据输入进去,然后将需要的结果输出。将程序的输入通道比喻成一个水管,输入的数据,比喻成水流,程序的输出通道也比喻成一个水管,输出的数据比喻成过滤之后的水流。那么我们可以称输入的数据,叫做输入流,输出的数据叫做输出流。关于输入,输出的通道,可以理解为:传送数据的各种总线。
笔者猜测这个流的概念应该最早来自于数据的抽象,不过现在有些书也将产生数据的对象叫做流,比如对于字符与键盘,键盘也叫做输入流,键盘产生的字符数据也可以叫做输入流,以后的文章中,将不会区分这两者。
对于一个程序来说,通常,默认的输入流,就是键盘,键盘也是标准输入,默认的输出流就是屏幕,屏幕也是标准输出。

标准输入用 0表示。
标准输出用 1表示。

当程序运行时,发生错误,需要将一些错误的信息输送出去,那么这些错误数据,也是流,叫做错误输出流。标准错误输出流也是屏幕,即错误输出信息,将会显示在屏幕上。

错误输出用 2表示

输入流重定向符 <

cat < wanbiao.txt

将wanbiao.txt里面的内容作为cat命令的输入。

输出流重定向符 1> 或者 1>>

ls -al 1> wanbiao.txt 

从wanbiao.txt文件的开头写入ls命令产生的输出

ls -al 1>> wanbiao.txt

从wanbiao.txt文件的末尾写入ls命令产生的输出,即追加在文件的末尾
对于输出流重定向符来说,可以省略数字1,即如下:

ls -al > wanbiao.txt
ls -al >> wanbiao.txt

错误输出重定向:2>或者2>> 示例如下:

ls -dl wanbiao 2> error.txt

表示将上面命令的错误信息输出到error.txt中。
同样2>>表示在文件的末尾,进行追加
通过上面的可以知道将普通输出和错误输出分开,可以使用不同的重定向符即可,如下:

ls -dl wanbiao > wanbiao.txt 2> error.txt

如果想将普通输出和错误输出,输出到同一个文件,可以使用下面的命令

ls -dl wanbiao > wanbiao.txt 2>&1

最后一个符号表示:“错误输出和1一样”。
有时为了简写也可写成如下的形式:

ls -dl wanbiao &> wanbiao.txt

表示将错误输出,和普通输出都输出到wanbiao.txt文件中。

注意:当你不想将一些命令的输出信息显示给用户,也不想保存在文件中,那么你可以将数据流重定向到/dev/null文件下。

/dev/null可以当成linux系统的回收站,垃圾桶。示例如下:

ls -dl wanbiao 2> /dev/null

表示将这个命令产生的错误信息,放到垃圾站中,不会显示在屏幕上。

4.2 here文档
上面在讲到输入流重定向的时候,只有一个<,没有<<。因为<<被当做了here文档的开始标志。这个名字听上去,非常不易理解。看见文档二字,以为是什么文档之类的东西。不过在这里需要提醒一句,重点并不在“文档”上,应该在here上,翻译成中文为:这儿。整体翻译就是:这儿文档。听上去好拗口!我更愿意翻译成:及时文档。重点就在这“及时”二字,及时在这里表示:当前看到的,没有保存的,用完就没了。举例如下:

cat << !wanbiao
1
2
3
!wanbiao

当输入cat << !wanbiao之后按下enter键。屏幕提示继续输入,这里输入1,再次按下enter键也没有结束,而是提示继续输入。直到输入!wanbiao之后,按下enter键才停止输入。
那么这是什么意思呢?
<<表示:后面是一个及时文档(即here文档),这个文档的结束符为<<跟着的第一个字符串。因此当你输入cat << !wanbiao之后按下enter键是告诉shell:cat的后面跟的是一个及时文档,这个文档以!wanbiao结束。因此shell在下一行给出提示让我们继续输入。直到输出遇到!wanbiao为止。
从1开始,到!wanbiao这几行就是一个文档,不过这个文档比较特殊,并不是在磁盘里面有一个文件来保存,而是直接在命令行里面,用完之后就没有了。这就是笔者为什么愿意将它翻译成:及时文档的原因。
那么这个及时文档有什么作用呢?
可以在shell脚本里面,向某个命令输入大量的文本参数。
可以将上面的文本:

cat << !wanbiao
1
2
3wanbiao

放入脚本中进行运行。
注意:当在及时文档中,定义一个结束符时,应该使用一些特殊的符号等如!wanbiao这样的特殊字符串,避免和文档的内容重复。

4.3 shell的管道命令
在上面中我们讲到了流的概念,它表示数据对象本身,或者表示数据源头本身。管道的作用就是连接两个流,不过这两个流比较特殊,都是标准流。我们使用一个竖线|表示管道。语言太苍白,示例如下:

ls -a . | grep -rn “wanbiao”

中间的竖线就是管道,连接了两个流,这两个流分别是:ls命令的输出流,和grep命令的输入流。
它连接起来的作用是:将ls的输出当成grep的输入,即ls命令的数据流直接流向命令grep而不是流向屏幕。
如果不使用管道,那么需要一个中间文档,先保存ls命令的输出,然后再将这个输出作为grep命令的输入使用,如下

ls -a . > ls.txt
grep -rn “wanbiao” ls.txt

这样操作特别的麻烦。

tee命令

ls -l / | tee -a root.txt

表示将ls -l / 命令产生在标准输出上的东西,传递给tee的标准输入。tee命令的作用就是将传递给他的数据,放到root.txt中。-a选项表示以累加的方式放入。

注意管道只能连接标准输出和输入,并不能连接标准出错输出

4.4 命令列表
当我们需要在某种情况下判断某些命令是否执行时,我们可以使用if进行判断。这里还有一种更加简单的操作。使用&&和||,这连个符号有点像c语言里面的逻辑与、逻辑或。
&& 表示:所有命令执行正确之后,才表示整个列表执行正确。*当第一命令执行正确之后,还需要判断第二命令是否执行正确。注意我们将&& 和|| 连起来的命令叫做命令列表,因为有很多个命令,只不过这些命令有一定的执行顺序罢了*)
|| 表示:任意一个命令执行正确,都表示整个列表执行正确。当第一个命令执行错误之后,后一个命令还需要执行才能明确是否执行正确。
语言太苍白了,可以参考一下c语言和java语言里面对于&&和||的说明,这里给一个示例:

ls -dl wanbiao && echoexit!”

当你按下enter键之后,ls -dl wanbiao如果执行正确了,但是还不能表示整个列表执行正确了,因此需要执行后面的echo “find it!”
如果ls -dl wanbiao执行错误,整个列表就是执行错误了,后面的就没有必要执行。
因此,有些书里面将&&说成:前面一个执行正确了,后面一个才执行,这其实是一个现象并不是本质。

ls -dl wanbiao || echo “sorry we don not find it

当按下enter键之后:如果ls -dl wanbiao执行正确,那么整个列表就正确了,后面的就不需要执行了。
如果ls -dl wanbiao执行错误,那么还需要执行后面的命令,用来判断整个列表是否执行正确。
因此,有些书里面将||说成了:前面一个执行错误之后,才会去执行后一个命令。

&&与||的优先级与结合性
他们两者优先级相同,结合性是从左向右,如下所示:

ls -dl wanbiao && echoexit” || echo “sorry we don not find it”

当你按下enter键,&&与||优先级相同,结合性从左向右,那么先运行
ls -dl wanbiao && echo “exit”
然后再将上面整个列表作为一个命令与后面的命令组成一个更大的列表进行操作。
当 ls -dl wanbiao && echo “exit” 中ls -dl wanbiao 执行成功,那么运行echo “find it” 整个命令执行成功,那么||后面的 echo “sorry we don not find it”将不会执行。
当 ls -dl wanbiao 执行错误,那么 ls -dl wanbiao && echo “exit”这个列表就表示执行错误,那么还需要判断|| 后面的命令的执行结果,因此执行echo “sorry we don not find it”

编写仓促,如有错误,烦请指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值