Linux学习笔记之八(重定向下和匿名进程管道)

接七。给出上一讲没有给出的一个例子。

上一讲讲的其实是输出重定向。今天我们来学习输入重定向。

输入重定向

上一讲已经说过/proc/pid/fd里面的0这个文件描述符对应的是标准输入,>或者1>是正确的输出,2>是错误信息,当然还有其它方式,上一讲里都有,0<,或者简写为<,就是输出的重定向符号,下面是一些例子。

第一个是发邮件的例子,需要先安装sendmai软件包和mailx。yum -y install sendmail mailx 即可。这里我试了一下,还必须要改/etc/hosts。在自己虚拟机的ip哪一行加一个主机名字加.com就可以了。效果如下:

下面才是我们重定向的重点。如何给一个用户发邮件呢?

mail 用户名就可以发给它邮件了,回车输入主题,再回车输入内容,怎么结束呢?另起一行,在行头打.回车就会自动出现EOT,就停止了。然后我们mail可以查看邮件,不加-u指定用户的话是看lcl用户的邮件(当然你还要有权限看)

root用户下mail -u root就可以看到刚才发给它的邮件了。左侧有一个邮件编号。在&后输入编号回车可以查看某一编号的邮件,输入q退出。上面这种是没有用到重定向的方式。

下面看一看重定向的方式:

重定向指定的是邮件的内容,主题得自己用-s指定了,后面必须加引号的。当然主题是可以为空的,如果你用了重定向而没有指定-s,那么主题就是空的。


案例2还是来看一下:

cat如果你不给文件路径就按回车,效果就是输入时默认从键盘输入,然后呢,你输什么回车它会重复打出来什么,grep呢,是你输入一行回车就过滤一行。给文件路径就可以有两种方式了,一种是作为参数,也就是不加<,一种是用输入重定向,这两种方法的不同就在于参数的个数不一样,效果是一样的,不过显然完全可以不加<,这里只是举例子而已,而且我试了一下重定向的参数按esc.也可以得到。

11.txt是通过输入重定向的方式作为cat的输入的,但是esc.也可以直接调出来。

案例三还是有点意思的,先来看dd命令。

只需要能看懂案例里的命令就可以了,不需要去细究。

再来看什么叫做/dev/zero文件。参考了https://blog.csdn.net/pi9nc/article/details/18257593

这个命令还是有点意思的,下面就会看到。

我们用df来看一下我们给的磁盘大小。

当时给的是50个G,上面加起来差不多。

但是呢,我们却能看到几百PB大小的文件。

当然这是假的,我们用了seek跳过了很多个块(block),file1.txt的真实大小只有1M,我们今天学习的重点不在于此,只是看一下。另外我们还看到dd可以测试磁盘的读写速度,804M/s。当然也可以用重定向来导入。

/dev/zero的特点就是无限输出0,如果不加count参数的节制的话,输出的文件大小会一直增加,直到把对应的分区占满,不加seek是很真实的,上面就是产生了一个1.5G的里面全是null的文件。


案例4由于需要MYSQL数据库基础,这讲我们学习的重点是输入重定向,就跳过了,想看的请到

https://www.bilibili.com/video/av18740388/?p=19,从第15分开始。

这里只是说明输入重定向还是很有用的。


用这个命令首先要yum -y install at。参考了

https://blog.csdn.net/gxiaop/article/details/55101020

需要先启动atd的。启动的方式变了,开机自启的命令也变了。

<EOT>不是打上去的,是按^D自动就有的。

说起来有点奇怪,不知道什么时候主机名又变成localhost了。enmmmm。这个是我自己的虚拟机啊 ,,原因还真不太清楚,不管了。

又三行的原因是回车并不是输入结束符,^d才是正常的输入结束符。

如果^c强制退出的话,只会把^c的上一行写入文件。

。可以用echo输入多行吗,可以,需要-e来解释转义字符。

但是需要引号把转义字符括起来。

还有其它转义字符比如\t,一个tab键也可以这么输出。

这里涉及到了脚本,脚本其实也好理解的,命令是你输一行执行一行,但是脚本就可以批量执行多行,当然执行还是一行一行来,但是输入只有一次,也不需要等一行命令执行完才可以输入下一个,提高了效率,就像在IDLE里只能一次执行一段for,但是在python脚本里面可以一次写入多个同等级的for语句,MATAB也是一样。脚本里面是没有人机交互的,那么以ctrl+d作为结束符的话就不太现实,这时候需要用<<来定义结束符,上面例子已经很好的说明了这一点。

后面还会学习脚本,这里先见一下,.sh是shell脚本的后缀,就像python后缀是py,c++后缀是cpp,matlab有m文件s文件。

再补充一点:

有的时候我们写代码需要缩进,对python来说更为重要。vim里怎么缩进可以参看。

https://jingyan.baidu.com/article/1612d5008ea0b8e20e1eee81.html

就是进入可视模式然后配合<或者>,也挺简单的。

但是<<后面定义的结束符必须顶头,不顶头就会报错,而且颜色也不是棕色的,那么这个时候我们可以在<<后面加-,这个时候结束符可以不顶头,但是必须是tab键,一般我们缩进也都是tab,而不是空格。

空格我试过了,确实不行,虽然eof还是棕黄色,但是确实会报错。

上面这个主要还是打印这个东西,用脚本的方式打印到终端。

有人可能会说这么麻烦有必要吗?当然必须要这样,在没有人机交互的情况下,计算机自动执行任务的时候必须用脚本。

综合案例4主要是为了说明多条命令输出重定向的方法。必须是小括号,其它的都不行。


其实这个;蛮好理解的,在c语言,MATLAB里也都是命令分隔符也就是一行可以写多个命令,不过c语言每段代码一个;是必须的,不然会报错,MATLAB不加;会直接输出,那样会很麻烦,数据多的时候你会看到命令窗口疯狂运动。

这里先补充学习一下终端的一些基本概念。参考了

https://blog.csdn.net/lcr_happy/article/details/59484514

/dev/ptmx是确实有的,是一个设备文件。

也就是说我们远程连接的时候用的都是伪终端。用tty可以查看当前终端,用w可以查看所有的终端,用pkill  9 -t pts/n可以终止终端,我们在虚拟机最小化安装的没有图形界面的里面的终端是tty,当然你需要登陆才行。

我是没有安装图形界面,如果你安装了图形界面的话可能会出现一个:0,这个是UI界面的终端号,gdm-sessio是UI界面。

我们了解到这里就可以了,我们远程连接的话都会给我们分配一个终端,当然可以用vnc连接图形界面的,我们没有UI的话就是pts/n。

匿名进程管道

进程管道其实也很简单,就是一个进程的输出作为另一个进程的输入,标准输入也就是1,左边进程的输出会作为右边进程的输入,中间的|就是一个匿名的管道。来看一下简单的效果。

如果直接ll /dev的话是很不人性化的,因为直接给你跳到了最后,后面加一个less就可以分页查看。

如果有错的话也是会显示的。


并且我们看到其实进程管道也是一种重定向,不过输出的方向对象不是文件而是进程的输入。

我们看到less的输入是一个管道pipe文件,这个文件是linux自动给你创建的。下面来看一下左边进程的文件描述符1,2会怎么样。

看到只有1重定向到了一个管道文件里面去了,说明和图上写的一样,是把标准输出也就是1重定向了,并且和less的fd里0对应的都是pipe22418,当然这种重定向也是一次性的。


上面还是一些例子,grep后面呢这个匹配的表达式暂时来说加不加引号没什么区别,不过最好加上去,后面会说为什么。

grep后面是可以用正则表达式的,^l就是以l开头的行。rpm那么命令就是查看已经装的软件包。而yum list是查看这个源里的软件,这些软件你不一定下载了,有@的都是下载了的。

这里先来学习sort的用法,sort其实也比较简单,默认是一个一个字符去比较来进行排序的,什么意思呢?

看到排序的时候1后面就是11,这是因为先按第一个字符排的话1的ascii码没有2大。

如果想按数值排序的话就需要加一个-n。

我们回来看案例1:

先看一下/etc/passwd。看到以冒号分割的话,第三行列是uid,第四列是gid,第7列是所用的shell。

就按照上面的命令来打一下,上面解释的很清楚,还是很好理解的,因为/etc/passwd和多行,我们就用head看一下前10行。

再逆序看一下:

分隔符默认是空格或者tab键。


并且呢,sort是不会改变原来文件的内容,只是对文件内容排序然后输出而已。

也许你会用重定向改变源文件,但是不行,因为这样做的结果是清空了源文件,但是可以输出到其它文件时没有问题的。

看到对3排序的结果可以输出到4里去,但是sort 3>3后发现3被清空了,而grep命令是会报错的,4不能同时作为输入和输出。


案例2的这行代码我们前面也见过,--sort和sort命令不同,--sort是ps的一个选项。

当然用sort也可以完成一样的功能,--sort=-%mem就是按照内存占用降序排序。head -6的原因是表头占了一行,不过发现用|sort的时候应该是-5,因为那个标题行没有了。并且其实 | 前面都可以不加空格的。

案例3用到了awk和uniq,awk是一个比较厉害的命令,不过这里用到的是很简单的功能了。参考了

https://www.cnblogs.com/xudong-bupt/p/3721210.html

字段就是分隔符之间的字符而已。

还有一个uniq,这个命令是去重的,不过必须是相邻的才行。

什么叫必须是相邻的呢?就是必须是相邻行才可以合并在一起的,那么这就得先排序一下了。

看一下效果:


案例5的话,先把有ip的行过滤出来,发现都有inet,就用这个过滤,但是发现inet6不是我们想要的行,怎么办呢,在匹配表达式后面加一个空格就可以。

这里就体现了引号的用处,如果不加引号,你在后面加空格也没用,因为根本就看不出来。

后面都是过滤ip的操作,后面那个/后面的数字是1的个数,其实就是掩码中1的个数,一个ip一共是有32位二进制数,最后把这个去掉就可以了。

案例6的话,应该看懂是不难的。

因为只需要根目录,所以用/$去匹配。

猜你喜欢

转载自blog.csdn.net/qq_41740705/article/details/81065635