探究Linux重定向

可能是命令行最酷的特性:I/O 重定向
”I/O”代表输入/输出, 通过这个工具,你可以重定向命令的输入输出,命令的输入来自文件,而输出也存到文件。
可以把多个命令连接起来组成一个强大的命令管道。

必须掌握以下命令:
cat - 连接文件
sort - 排序文本行
uniq - 报道或省略重复行
grep - 打印匹配行
wc - 打印文件中换行符,字,和字节个数
head - 输出文件第一部分
tail - 输出文件最后一部分

一般地,像命令ls,输出送到屏幕,输入来自键盘, 但是通过 I/O 重定向,我们可以改变输入输出方向。


重定向标准输出

I/O 重定向允许我们来重定义标准输出送到哪里。
重定向标准输出到另一个文件除了屏幕,我们使用 “>” 重定向符,其后跟着文件名。

为什么我们要这样做呢?
因为有时候把一个命令的运行结果存储到 一个文件很有用处,比如:

把 ls 命令的运行结果输送到文件 ls-output.txt 中去, 由文件代替屏幕:

[me@linuxbox ~]$ ls -l /usr/bin > ls-output.txt

检查一下重定向的命令输出结果:

[me@linuxbox ~]$ ls -l ls-output.txt
-rw-rw-r-- 1   me   me    167878 2015-10-26 15:07 ls-output.txt

我们可以用 less 阅读器来查看这个文件,我们会看到文件 ls-output.txt 的确包含 ls 命令的执行结果。

[me@linuxbox ~]$ less ls-output.txt

可以看到txt文本内容确实为ls -l ls-output.txt命令执行的结果。

简单地使用重定向符,没有命令在它之前,这会删除一个已存在文件的内容或是创建一个新的空文件。

[me@linuxbox ~]$ > ls-output.txt

这是因为,当我们使用 “>” 重定向符来重定向输出结果时,目标文件总是从开头被重写。

所以,怎样才能把重定向结果追加到文件内容后面,而不是从开头重写文件?
为了这个目的, 我们使用”>>“重定向符,像这样:

[me@linuxbox ~]$ ls -l /usr/bin >> ls-output.txt

重定向标准错误

重定向标准错误缺乏专用的重定向操作符。
我们必须把这些文件流的前 三个看作标准输入,输出错误,shell 内部参考它们为文件描述符0,12。

shell 提供 了一种表示法来重定向文件,使用文件描述符:

[me@linuxbox ~]$ ls -l /bin/usr 2> ls-error.txt

文件描述符“2”,紧挨着放在重定向操作符之前,来执行重定向标准错误到文件 ls-error.txt 任务。


重定向标准输出和错误到同一个文件

同时重定向标准输出和标准错误,有两种方法来完成任务。
第一个,传统的方法, 在旧版本 shell 中也有效:

[me@linuxbox ~]$ ls -l /bin/usr > ls-output.txt 2>&1

首先重定向标准输出到文件 ls-output.txt,然后重定向文件描述符2(标准错误)到文件描述符1(标准输出)使用表示法2>&1

注意重定向的顺序安排非常重要。标准错误的重定向必须总是出现在标准输出 重定向之后,要不然它不起作用。

现在的 bash 版本提供了第二种方法:

[me@linuxbox ~]$ ls -l /bin/usr &> ls-output.txt

在这个例子里面,我们使用单单一个表示法 &> 来重定向标准输出和错误到文件 ls-output.txt。


处理不需要的输出

系统为我们提供了处理不需要的输出的方法,通过重定向输出结果 到一个特殊的叫做”/dev/null”的文件。
这个文件是系统设备,叫做位存储桶,它可以接受输入,并且对输入不做任何处理。为了隐瞒命令错误信息,我们这样做:

[me@linuxbox ~]$ ls -l /bin/usr 2> /dev/null

重定向标准输入

cat - 连接文件
cat 命令读取一个或多个文件,然后复制它们到标准输出,就像这样:

cat [file]

可以使用 cat 来显示文件而没有分页,例如:

[me@linuxbox ~]$ cat ls-output.txt

将会显示文件 ls-output.txt 的内容。
cat 经常被用来显示简短的文本文件。

如果 cat 没有给出任何参数,它会从标准输入读入数据,因为标准输入,默认情况下,连接到键盘。

比方说,我们想创建一个叫做”lazy_dog.txt” 的文件,这个文件包含例子中的文本:

[me@linuxbox ~]$ cat > lazy_dog.txt
my name is yu.

记住,最后输入 Ctrl-d

看一下运行结果,我们使用 cat 来复制文件内容到 标准输出:

[me@linuxbox ~]$ cat lazy_dog.txt
my name is yu.

重定向标准输入:

[me@linuxbox ~]$ cat < lazy_dog.txt

使用“<”重定向操作符,我们把标准输入源从键盘改到文件 lazy_dog.txt。


管道线

命令可以从标准输入读取数据,然后再把数据输送到标准输出,命令的这种能力被一个shell 特性所利用,这个特性叫做管道线
使用管道操作符”|”(竖杠),一个命令的 标准输出可以管道到另一个命令的标准输入:

command1 | command2

用 less 来一页一页地显示任何命令的输出,命令把 它的运行结果输送到标准输出:

[me@linuxbox ~]$ ls -l /usr/bin | less

使用这项技术,我们可以方便地检测会产生标准输出的任一命令的运行结果。


过滤器

管道线经常用来对数据完成复杂的操作。
有可能会把几个命令放在一起组成一个管道线,以这种方式使用的命令被称为过滤器

过滤器接受输入,以某种方式改变它,然后输出它

试验过滤器 sort:
把目录/bin 和/usr/bin 中 的可执行程序都联合在一起,再把它们排序,然后浏览执行结果:

[me@linuxbox ~]$ ls -l /usr/bin | sort | less

ls 命令的输出结果由有序列表组成,通过在管道线中包含 sort,我们改变输出数据,从而产生一个有序列表。


uniq - 报道或忽略重复行

uniq 命令经常和 sort 命令结合在一起使用。
uniq 从标准输入或单个文件名参数接受数据有序 列表(详情查看 uniq 手册页),默认情况下,从数据列表中删除任何重复行。

添加 uniq 到管道线中:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq | less

如果我们想看到重复的数据列表,让 uniq 命令带上”-d”选项,就像这样:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq -d | less

wc - 打印行,字和字节数

wc命令是用来显示文件所包含的行,字和字节数。例如:

[me@linuxbox ~]$ wc ls-output.txt
7902 64566 503634 ls-output.txt

以上数字分别表示文件ls-output.txt 中的行数单词数字节数

-l”选项限制命令输出只报道行数。
查看我们的有序列表中程序个数, 我们可以这样做:

[me@linuxbox ~]$ ls  /usr/bin | sort | uniq | wc -l
2728

grep - 打印匹配行

grep 是个很强大的程序,用来找到文件中的匹配文本。这样使用 grep 命令:

grep pattern [file...]

在我们的程序列表中,找到文件名中包含单词”zip”的所有文件:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq | grep zip
bunzip2
bzip2
gunzip

grep 有一对方便的选项:
-i”导致 grep 忽略大小写当执行搜索时(通常,搜索是大小写 敏感的)。
-v”选项会告诉 grep 只打印不匹配的行


head / tail - 打印文件开头部分/结尾部分

head 命令打印文件的前10行,而 tail 命令打印文件的后10行。
默认情况下,两个命令都打印十行文本,但是可以通过”-n”选项来调整命令打印的行数:

[me@linuxbox ~]$ head -n 5 ls-output.txt
total 343496
...
[me@linuxbox ~]$ tail -n 5 ls-output.txt
...

也能用在管道线中:

[me@linuxbox ~]$ ls /usr/bin | tail -n 5

tail 有一个选项允许你实时的浏览文件。

[me@linuxbox ~]$ tail -f /var/log/messages
Feb 8 13:40:05 twin4 dhclient: DHCPACK from 192.168.1.1

使用”-f”选项,tail 命令继续监测这个文件,当新的内容添加到文件后,它们会立即出现在屏幕上。
输入 Ctrl-c退出。


tee - 从 Stdin 读取数据,并同时输出到 Stdout 和文件

tee 程序从标准输入读入数据,并且同时复制数据 到标准输出(允许数据继续随着管道线流动)和一个或多个文件。

使用tee 命令,在 grep 过滤管道线的内容之前,来捕捉整个目录列表到文件 ls.txt:

[me@linuxbox ~]$ ls /usr/bin | tee ls.txt | grep zip
bunzip2
bzip2

[me@linuxbox ~]$ cat ls.txt

ls.txt里面保存的是命令ls /usr/bin的结果。


知识来源:http://billie66.github.io/TLCL/book/zh/chap07.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值