linux基础知识-22

一、标准输入和标准输出

终端程序一般以流的形式读取信息,如:从键盘读取信息。之后以流的形式写入目的地,如显示器。

在linux中标准输入是:stdin(键盘),标准输出是:stdout(显示器)

(一)将输出写入文件

一般把输出写到标准输出流中,这样就在显示器中显示了。但bash shell可以通过 > 重定向运算符把流向标准输出流的数据重定向到文件中。比如:

linux@myccloves:~/test$ ps aux > 1

当执行ps aux时,程序的结果输出到标准输出流中,所以在显示器中显示,但现在通过重定向输出到文件中了。

(二)把输出追加到文件中

当我们第一次把数据写到文件“1”中,再运行一次则会覆盖文件“1”,这样造成原先数据丢失。为了解决这类问题,可以把输出追加到文件中。如:

ps aux >> 1

用两个 > 就可以了。

(三)重定向标准输入

我们从键盘输入数据,流向程序中。换一种说法就是从键盘读取数据,现在我想从文件中读取数据。

我们以mail命令来说明这个问题:(我的测试环境是在虚拟机中:centos系统)

先来说点题外话:mail命令可以在终端发送电子邮件,但是必须进行mail的配置和网页端邮件的配置,老陌已经配置完,所以可以发送电子邮件。

回正题,我们通过mail命令发送电子邮件,其中 -s 表示信的标题,后面的邮箱表示发送给谁(目的邮箱)。 之后是重点,mail等用户输入正文…… 输入完成按ctrl+d结束输入,之后自动发送。这里面通过键盘也就是标准输入,输入数据到mail程序中,如果我们能够从其它地方输入数据,而不是从键盘,就需要用到重定向标准输入。

程序 < 文件

本来程序,通过键盘输入,现在通过文件进行输入,也就是把文件的内容送到程序里。如:

这一次我们发现,程序并没有让我们输入正文,原因是正文在letter这个文件里,通过重定向 <letter改变了标准输入,原先从键盘中读取数据,现在从letter文件中读取数据。

如果您感觉mail命令无法测试,可以用cat

cat命令原先从键盘读取数据,后来用 <letter,则从letter中读取数据了。

二、标准错误

标准错误和标准输出基本一样,标准错误也是一个输出流,用来报告出错状态信息,称为: stderr

我们来看一下例子来理解标准错误:

首先 head -2 /etc/passwd 输出的信息送到标准输出流中。
之后 head -2 /etc/shadow 输出的信息原先准备送到标准输出流中,但遇到了错误,所以送到标准错误输出流中,此时发现他们一样,怎么能说明这条命令是把信息送到标准错误输出流中呢?

为了验证一下,我们把输出信息重定向到文件中: head -2 /etc/passwd > 1.txt 此时发现输出信息流向了1.txt中。
之后执行 head -2 /etc/shadow > 2.txt,你会发现,怎么信息没有被重定向呢? 不是写到2.txt中才正确吗?

有了这个疑问,我们应该知道了stdout,stderr不是同一个输出流:

通过这个图我们看出,命令出错时走的是stderr,命令正常输出走的是 stdout, 所以我们 >2.txt 没有起作用,因为他只重定向标准输出流,而错误输出流并不是通过>运算符来重定向的。

(一) 标准错误输出流

同标准输出流重定向类似,标准错误输出流用2>来定义。

[cclove@localhost ~]$ head /etc/shadow 2> 2.txt
[cclove@localhost ~]$ cat 2.txt
head: cannot open ‘/etc/shadow’ for reading: Permission denied
[cclove@localhost ~]$ 

这回用2>把错误信息重定向到2.txt中,发现这回正确了,查看2.txt果然如此。

(二) 合并标准输出和标准错误

我们用head命令同时查看两个文件,并把查看的信息重定向到 1.txt 中,错误的信息重定向到2.txt中。 经检测一切正常,只不过写到一行了。现在我们要把这些信息都放到1.txt中.

[cclove@localhost ~]$ head -2 /etc/passwd /etc/shadow >1.txt 2>1.txt
[cclove@localhost ~]$ cat 1.txt
head: cannot open ‘/etc/shadow’ for reading: Permission denied
linux@myccloves:~$ head -2 /etc/passwd /etc/shadow >1.txt 2>1.txt
bin:/sbin/nologin

这回我们把两个信息流都重定向到1.txt中,但查看和我们想像的结果不一样。因为在重向时,需要打开文件,但同一个文件被打开两次,最终进行了互相伤害,导致文件损坏。为了防止这种事情发生,我们应该有效的结合两个输出流,合并为一个流。

这回正确了,2>&1表示,把错误流送到标准输出流中,这样就整合到一起了。 上面讨论的是老式的作法,为了简化现在用>&来实现。

linux@myccloves:~$ head -2 /etc/passwd /etc/shadow >& 1.txt

重定向总结一下:

重定向 说明
cmd < file 从file重定向到标准输入。
cmd > file 把标准输出重向定到file中,如果file存在,覆盖。
cmd >> file 把标准输出重向定到file中,如果file存在,追加。
cmd 2> file 把标准错误重向定到file中,如果file存在,覆盖。
cmd 2>> file 把标准错误重向定到file中,如果file存在,追加。
cmd > file 2>&1 合并标准输出和标准错误输出,并且重定向到file中
cmd >& file 合并标准输出和标准错误输出,并且重定向到file中

三、管道

所谓管道(pipe)就是一个程序的数据输出,被管道送到另一个程序的输入,即:另一个程序读取被送来的数据。

我们一步一步理解:

linux@myccloves:~$ cat /etc/os-release 
PRETTY_NAME="Deepin 15"
NAME="Deepin"
VERSION_ID="15.6"
VERSION="15.6"
ID=deepin
HOME_URL="https://www.deepin.org/"
BUG_REPORT_URL="http://feedback.deepin.org/feedback/"

我们用cat查看一个文件,发现这里的行,不是按字母表的顺序排列的。linux中有一个sort命令可以排序。

linux@myccloves:~$ sort /etc/os-release 
BUG_REPORT_URL="http://feedback.deepin.org/feedback/"
HOME_URL="https://www.deepin.org/"
ID=deepin
NAME="Deepin"
PRETTY_NAME="Deepin 15"
VERSION="15.6"
VERSION_ID="15.6"

这回我们观察,这些行按字母的顺序排序了。

这两步能不能合成一步呢? 首先cat把os-release的内容输出,之后sort读取/etc/os-release的内容。一个进程输出,别一个进行需要输入,这种需求正符合管道的思想,所以合并一下:

linux@myccloves:~$ cat /etc/os-release | sort
BUG_REPORT_URL="http://feedback.deepin.org/feedback/"
HOME_URL="https://www.deepin.org/"
ID=deepin
NAME="Deepin"
PRETTY_NAME="Deepin 15"
VERSION="15.6"
VERSION_ID="15.6"

管道一般与grep组合,用于查看感兴趣的文本行,比如:我们要查看linux用户的信息

linux@myccloves:~$ cat /etc/passwd  | grep linux
linux : x : 1000 : 1000 :: /home/linux : /bin/bash

grep 从管道读取传递过来的数据,之后查找有linux字样的文本行就打印出来。这个功能很常用也很强大。当然grep本身也可以读取文件进行查找,比如:

linux@myccloves:~$ grep linux /etc/passwd 
linux : x : 1000 : 1000 :: /home/linux : /bin/bash

注意:管道遇到标准错误时,标准错误是不流向管道的,所以会正常输出到错误输出流中。

linux@myccloves:~$ cat /etc/shadow | grep linux
cat: /etc/shadow: Permission denied
posted @ 2018-07-23 07:36  老陌  阅读(225)  评论(0编辑  收藏  举报