Shell Programming(一)——重定向与管道

来源:互联网 发布:itools for mac录屏 编辑:程序博客网 时间:2024/05/24 06:40

Shell Programming(一)——重定向与管道

概述

​ 很长时间没在Linux进行开发,很多Linux Shell相关的点都快忘了。今天重新捡起来,也做一点记录,以便后续遇到相关问题可以有笔记可查。

​ Linux下的开发,很多地方都离不开Shell脚本的编写,一些批处理操作,打包之类的,要想快速高效地做好Linux开发,还是要对Shell熟悉啊。这里先从两个比较常用的功能说起。

重定向

​ 大多数Unix/Linux Shell都支持重定向,重定向用于改变标准流的接受者,比如”ls”命令会将路径下的文件信息输出到终端上,也就是输出到标准输出(1),使用重定向就可以将输出流输出到一个文件,或者其他可以接受输入的命令上。

不做重定向的ls命令应该得到的结果是这样的:

➜ shell git:(master) ✗ ls -l

total 8

-rw-r–r– 1 Morris staff 40 5 15 16:40 test.txt

➜ shell git:(master) ✗

如果ls的结果数量比较大,我们又需要根据某些模糊匹配去搜索一些结果,这时单纯地靠眼睛看就很累了。这里可以使用的一种方式就是,将ls结果重定向到一个文本文件中,再通过编辑器去查找我们需要的内容,就像这样:

➜ shell git:(master) ✗ ls -l > test.txt

➜ shell git:(master) ✗ more test.txt

total 0

-rw-r–r– 1 Morris staff 0 5 16 09:15 test.txt

➜ shell git:(master) ✗

​ 以上就是重定向的一点简单使用,这里则需要补充一点标准流的相关知识。每个进程打开时,都会默认地打开3个文件描述符——0, 1, 2,三者分别代表:标准输入标准输出标准错误输出。上文中,ls默认的标准流接收者就是1(标准输出),即可在终端上显示结果。一个命令的成功或者失败的执行,都会在终端上显示结果(成功时,这个结果可能是空的。),但它的标准流的接收者有区别,对于成功的情况,一般接收者是1(标准输出),而失败的情况,一般接收者是2(标准错误输出),只是最终它们都被显示到了终端上,这点要注意区分。

​ 对于标准输入来说,诸如read这样的命令就会在终端等待一个用户输入,用户输入的标准流默认接收者就是0(标准输入),就像这样:

➜ shell git:(master) ✗ read val

123

➜ shell git:(master) ✗ echo ${val}

123

➜ shell git:(master) ✗

​ 如果需要的用户输入来自于一个文件,我们也可以使用重定向的手段,将文件内容传递给read,就像这样:

➜ shell git:(master) ✗ read val

123

➜ shell git:(master) ✗ echo ${val}

123

➜ shell git:(master) ✗ read val < test.txt

➜ shell git:(master) ✗ echo ${val}

total 0

➜ shell git:(master) ✗ more test.txt

total 0

-rw-r–r– 1 Morris staff 0 5 16 09:15 test.txt

➜ shell git:(master) ✗

补充说明:read接受的是一个以换行结束的字符串,所以仅能读取到test.txt的第一行。

​ 重定向到标准输入,只有一个’<’符号,没什么不明确的内容,不过,对于重定向标准输出和标准错误输出就有点不明确了,都是使用’>’,如何区分呢?这里我们就可以明确指明重定向的是标准输出还是标准错误输出,比如重定向标准输出可以这样:

➜ shell git:(master) ✗ more test.txt

➜ shell git:(master) ✗ ls -l 1> test.txt

➜ shell git:(master) ✗ more test.txt

total 0

-rw-r–r– 1 Morris staff 0 5 16 10:13 test.txt

➜ shell git:(master) ✗

以上操作则可以把标准流从标准输出重定向到test.txt文件了。

考虑这样一种情况,如果使用2>呢?尝试之后,我们会发现test.txt文件内容为空,原先的内容被覆盖了。原因是,ls执行成功,标准错误输出为空,所以test.txt被写为空。如果我们需要将标准输出和标准错误输出都重定向到同一个文件怎么做呢?我们可以这样:

➜ shell git:(master) ✗ kill -HUP 1234 1> test.txt 2>&1

➜ shell git:(master) ✗ more test.txt

kill: kill 1234 failed: no such process

➜ shell git:(master) ✗

注意末尾的2>&1,这里一定要写对。

管道

​ 回想上面提到的一个问题,如果要对ls的结果进行筛选、查找,可以将结果重定向再去进行文本查找。这样可能需要额外创建一个文件来做操作,不过使用管道就简单多了。

​ 管道是Linux用于连接多个进程,并在多个进程间进行有向有协调的数据流动的工具。首先说有向,数据在管道的流向是从前一个进程流向后一个进程,这里的前后以’|’来区分,’|’之前的就是前一个进程,之后的是后一个进程;有协调,数据在流动的过程中,同步是不需要我们自己来做的,Linux Shell已经为我们做好了,所以不需要我们额外考虑同步问题。有了上面的了解,我们也可以用管道来改写上面提到的ls结果进行筛选查找的问题了:

➜ shell git:(master) ✗ ls -l

total 8

-rw-r–r– 1 Morris staff 60 5 16 10:29 test.txt

➜ shell git:(master) ✗ ls -l | grep test

-rw-r–r– 1 Morris staff 60 5 16 10:29 test.txt

➜ shell git:(master) ✗

​ 使用方式很灵活,可以连接多个命令,更多的经验可以多多尝试总结。

原创粉丝点击