shell程序设计(一)管道和重定向

Bash ginotang 774℃ 0评论

管道和重定向

在shell中,通过管道,可以使一条命令的输出结果作为另一条命令的输入数据,管道操作符为“|”(竖线)。一般的shell都包含三个标准文件描述符:标准输入(0)、标准输出(1)以及标准错误(2)。而我们可以把这三个标准文件描述符的操作进行重定向,例如把输出到屏幕(标准输出)的结果重定向到磁盘中的普通文件。又如把标准错误重定向到系统中的黑洞中去(/dev/null)。

管道

管道用于把一个命令的输出作为另一个命令的输入,管道在linux系统的使用过程中十分常见。

例如,找出最新创建的文件:

上面的命令中,ls命令的输出会通过管道操作符传输到head命令,head命令把这些数据作为输入来啊处理。

临时重定向

重定向分为临时重定向和永久重定向,临时重定向只影响当前执行重定向的语句,而永久重定向则影响当前执行的脚本。

重定向标准输出

上面的例子中使用了“>“操作符,它的作用是把数据重定向到指定文件,如果文件已经存在,则覆盖这个文件。如果希望改变该操作符的这个默认行为,可以使用下面的指令:

之后任何重定向到已存在文件的行为都会失败,会输出错误信息:cannot overwrite existing file

可以使用下面的命令进行还原:

重定向的另一个操作符是”>>“, 它和上面的操作符的唯一不同是:它不会覆盖已经存在的文件,而是把内容追加到文件的末尾。

除了把标准输出重定向到文件,我们还可以重定向到其他地方,例如标准错误输出:

注意重定向符号(>)和&之间不能有空格。

重定向标准错误输出

标准错误是我们在操作shell的时候返回的错误信息,默认情况下,shell会直接把这些错误消息直接显示出来。在使用”>“或”>>“操作符的时候,它默认操作的是标准输出,我们可以在这两个符号前面添加标准错误描述符来改变这个行为。

例如,假设not_exist是一个不存在的文件夹,下面的操作会返回错误信息:

上面的命令可以拆分为两条命令理解:ls -l . 和 ls -l /not_exist。

第一条命令输出的内容会被正确重定向到result.txt文件中,由于/not_exist是一个不存在的目录,我们又另外设置了错误信息的保存位置,因此错误信息被重定向到error.txt。

下面是另外一种常见的重定向操作:

意思是:将标准输出重定向到文件result.txt,然后将标准错误输出重定向到与标准输出相同的地方。

重定向所有输出

除了可以分别重定向标准输出和错误输出外,还可以同时重定向它们,使用&>即可。例如:

重定向标准输入

这种重定向相比起前面的两种,较为少用,因为在终端中,一般的命令都可以使用文件名作为参数,而不需要把文件的内容传递给这个程序,以grep为例子:

grep是一个文本查找工具,它的参数通常是grep <要查找的字符串> <目标文件名>,而不是grep <要查找的字符串> <目标字符串>

又如:

虽然可以这样做,但是显得有点多余。

另一种常见的输入重定向是:

永久从定向

永久重定向需要使用exec命令。

重定向标准输出

下面是使用exec重定向标准输出的例子:

把标准输出重定向到testout.txt文件,当执行完这条命令之后,后续的所有输出都会被发送到testout.txt,屏幕上面不会有任何输出,除了错误输出外。

标准错误的重定向基本和标准输出的一样,只是文件描述符不一样:

重定向标准输入

通常可以把文件绑定到标准输入,这样可以直接从文件读取内容,然后输出到屏幕。

标准输入绑定到文件data1.txt后,read命令就直接从这个文件中读取内容,然后输出到屏幕。

使用其他文件描述符

在Linux系统中,我们可以打开的文件描述符有9个,除了三个基本的:0,1,2。我们还可以使用的描述符是3~8。

例如我们可以把其他文件描述符绑定到文件,标准输出等等。

运行结果:

描述符之间的绑定和还原

通过额外可用的文件描述符(3~8),可以使描述符之间互相绑定和还原。

例子:

执行结果:

读写一体的描述符

我们甚至可以同时把输入和输出重定向到同一个文件描述符,但当我们这样做的时候,最好清楚这样做的后果。

testfile文件的内容如下:

当脚本运行结束,testfile的内容是:

最后一行只剩下third line。其他的被覆盖了。

造成这种现象的原因是:文件内部有一个指针,这个指针记录着当前文件的读写位置,当脚本中的read结束(读完第一行),这个指针就处于第二行的开头,所以使用echo输出的时候,从这个位置开始写入数据,写入的这些数据会覆盖原来的数据,因此会开到第三行的数据也被覆盖了。注意:换行符(’\n’)虽然看不见,但是它同样会被覆盖。

看下面的演示:

第一行的第二个This前面实际上有一个看不到的换行符,为了方便对比,把它和第二行数据放到同一行中。

third line. 这些字符实际上是遇到被替换后的数据中的换行符后才换行的。

关闭文件描述符

当我们打开了新的文件描述符,当shell执行完脚本结束的时候会自动关闭这些描述符。如果希望在脚本结束前关闭这些描述符,可以使用&-组合符号。通过把打开的描述符重定向到这个组合符号即可关闭它们。

 

一点问题

在使用重定向的时候,千万不能使用相同的文件,原因在于,后运行的命令中使用的文件会把先运行命令所使用的同名文件覆盖。

举个例子:

命令运行之后mydata.txt会变成一个空的文件,因为在读取文件之前就已经覆盖了这个文件的内容。

 

转载请注明:Pure nonsense » shell程序设计(一)管道和重定向

喜欢 (1)
0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x
()
x