Linux基础之IO重定向及管道详解(涉及tr、tee命令)

    我在刚开始接触IO重定向时,经历了由懂到不懂然后了然的过程,当然现在的我也不可能说对于IO重定向就彻底懂了,只是在解决一些问题或实现某些结果时不会因为IO重定向的问题而迷惑了。

   


    什么叫IO重定向?

为了解释这个问题,我们要先明白什么叫IO,什么叫做程序的数据流。

     什么叫IO?

在Linux或计算机领域IO指的是信息的输入和输出。

在Linux中可用于输入的设备:文件(Linux中一切皆文件)

具体包括:键盘设备、文件系统上的常规文件、网卡等。

在Linux中用于输出的设备:文件

具体包括:显示器、文件系统上的常规文件、网卡等。

    什么叫做数据流?

我们通常描述的信息本质上来说都是数据,因为信息处于动态,我们就将信息或者命令等概念称作流动的数据也就是数据流。

数据流分为输入流(InputStream)和输出流(OutputStream)两类。输入流只能读不能写,而输出流只能写不能读。通常程序中使用输入流读出数据,输出流写入数据,就好像数据流入到程序并从程序中流出。采用数据流使程序的输入输出操作独立与相关设备。输入流可从键盘或文件中获得数据,输出流可向显示器、打印机或文件中传输数据。

    在Linux中,程序的数据流有三种:

输入的数据流:←标准输入 STDIN 常用设备:键盘

输出的数据流:→标准输出 STDOUT 常用设备:终端

错误输出流: →错误输出 STDERR 常用设备:终端

在Linux中打开一个文件,在该文件被加载完成后对于系统来说需要用一个数字表示,这个数字叫做fd:file descriptor 文件描述符。

因为Linux系统中一切皆文件,所以对应的标准输入设备,标准输出设备,错误输出设备都有其对应的fd

    标准输入:0

    标准输出:1

    错误输出:2

    IO重定向的意思就是将系统原本默认的输入输出的路径重新定向到其他文件

我知道解释到这里还是会很困惑,别着急,这个概念需要通过一定量的实验来说明。



    输出重定向

    其常用 >>>>|这三种表示

    >:覆盖输出  >>:追加输出  >|:强行覆盖

因为使用>不当会对原有的数据造成很大的影响,所以有时候我们会手动设定关闭>的特性。其命令为:

set -C禁止覆盖输出重定功能

set +C为开启覆盖输出重定向功能

不过上述命令对“>|”无效

下面以具体实验来说明上面内容

实验环境:在/test/目录下

[root@localhost test]# ll
总用量 0
[root@localhost test]# echo $(date) > t1
[root@localhost test]# ll
总用量 4
-rw-r--r--. 1 root root 43 8月   2 18:15 t1
[root@localhost test]# cat t1
2016年 08月 02日 星期二 18:15:28 CST
[root@localhost test]# echo test > t1
[root@localhost test]# cat t1
test
[root@localhost test]# echo $(who) >> t1
[root@localhost test]# cat t1
test
root :0 2016-08-02 10:12 (:0) root pts/0 2016-08-02 10:12 (192.168.85.1) root pts/1 2016-08-02 10:19 (192.168.85.1)
[root@localhost test]# set -C
[root@localhost test]# echo 111 > t1
-bash: t1: 无法覆盖已存在的文件
[root@localhost test]# echo 111 >| t1
[root@localhost test]# cat t1
111

上面的结果显示了>、>>、>|三者的各自功能

相信看到这里对于输入重定向会有了进一步的认识。



    错误输出流重定向 

    2>

[root@localhost test]# echoo 1 > t2
bash: echoo: 未找到命令...

当命令错误时,shell会返回错误信息,若我们想将错误信息存到某个文件则可按如下操作

[root@localhost test]# echoo 1 2> t2
-bash: t2: 无法覆盖已存在的文件
[root@localhost test]# ll
总用量 4
-rw-r--r--. 1 root root 4 8月   2 18:18 t1
-rw-r--r--. 1 root root 0 8月   2 18:20 t2
[root@localhost test]# echoo 1 2> t3
[root@localhost test]# cat t3
bash: echoo: 未找到命令...
[root@localhost test]# echop wqew 2>>t3
[root@localhost test]# cat t3
bash: echoo: 未找到命令...
相似命令是: 'echo'
bash: echop: 未找到命令...

错误重定向也支持追加。

如果我们不管命令对错都想记录那么可以使用如下格式实现:

1、&>&>>

[root@localhost test]# ech2 &>> t4
[root@localhost test]# echo right &>> t4
[root@localhost test]# cat t4
bash: ech2: 未找到命令...
right

2、command >> /path/somewhere ... 2>&1  第二种只能为此种格式,不管前面是追加还是覆盖后面均为2>&1。2>>&1为错误格式,使用后在centos7.2下会报错。

[root@localhost test]# ech2 >> t5 2>&1      
[root@localhost test]# echo right >> t5 2>&1
[root@localhost test]# cat t5
bash: ech2: 未找到命令...
right

注:输出重定向的对象可以是各种文件,但不能将其定向至命令的输入,要想实现这个功能则需要用管道。这里大家可能有点迷,下面以例子说明

[root@localhost test]# who > tr a-z A-Z > t6
[root@localhost test]# cat t6
root     pts/0        2016-08-02 10:12 (192.168.85.1)
[root@localhost test]# ll
总用量 4
-rw-r--r--. 1 root root 54 8月   2 18:53 t6
-rw-r--r--. 1 root root  0 8月   2 18:53 tr

我们将who显示的命令重定向至tr命令的输入,之后将内容小写转换为大写后再重定向至t6文件。我们想实现的是这个结果,但是并没有实现,反而在过程中出现了tr这个文件。这是因为在第一层的重定向中,默认将tr当做文件名,但是奇怪的是tr内什么都没有,所以这种错误的理解尽早摆脱。

[root@localhost test]# cat tr 
[root@localhost test]#

我们可以使用管道完美解决上面的问题。

[root@localhost test]# who | tr a-z A-Z > t6
[root@localhost test]# cat t6
ROOT     :0           2016-08-02 10:12 (:0)
ROOT     PTS/0        2016-08-02 10:12 (192.168.85.1)
ROOT     PTS/1        2016-08-02 10:19 (192.168.85.1)

什么是管道,我相信通过上面的例子大家应该对它有了个初步的认知。


管道:连接程序,实现将前一个命令的输出直接定向后一个程序当做输入数据流。

其常用表达格式如下:  COMMAND1 | COMMAND2 | COMMAND3 |...

它是输出重定向的补充与加强,其本质还是类属于输出重定向。

既然说道管道,这里再多补充点

常用于管道的命令:

tee

tee - read from standard input and write to standard output and files

      显示标准输入的结果并将其写入文件

    tee的使用格式:

    命令1 | tee 文件名| 命令2

把命令1的STDOUT保存在文件名中,然后管道输入给命令2

作用:

    保存不同阶段的输出

    复杂管道的故障排除

    同时查看和记录输出

下面通过一个简单的例子说明tee的具体作用

[root@localhost test]# who | tee t2 | tr a-z A-Z
ROOT     :0           2016-08-02 10:12 (:0)
ROOT     PTS/0        2016-08-02 10:12 (192.168.85.1)
ROOT     PTS/1        2016-08-02 10:19 (192.168.85.1)
[root@localhost test]# cat t2
root     :0           2016-08-02 10:12 (:0)
root     pts/0        2016-08-02 10:12 (192.168.85.1)
root     pts/1        2016-08-02 10:19 (192.168.85.1)

tee可以将前一个的结果记录在t2文件内,同时显示后一个命令的结果。




    输入重定向

     < 单行模式、 << 多行模式

要了解输入重定向,我们得先了解一个命令

tr

 tr - translate or delete characters 转换或删除字符

其表达格式如下:

    tr[OPTION]... SET1 [SET2]

选项:

    -c或——complerment:取字符集的补集

    -d或——delete:删除所有属于第一字符集的字符

    -s或—squeeze-repeats:把连续重复的字符以单独一个字符表示

下面我们通过一个例子简要了解下tr的作用

[root@localhost test]# cat t1
root     :0           2016-08-02 10:12 (:0)
root     pts/0        2016-08-02 10:12 (192.168.85.1)
root     pts/1        2016-08-02 10:19 (192.168.85.1)
[root@localhost test]# tr a-z A-Z < t1
ROOT     :0           2016-08-02 10:12 (:0)
ROOT     PTS/0        2016-08-02 10:12 (192.168.85.1)
ROOT     PTS/1        2016-08-02 10:19 (192.168.85.1)

t1是上面tee存储的who内容,我们通过输入重定向将其作为tr的输入,并由小写转换为大写。

输入重定向就是将原来用键盘输入的内容通过其他文本内容或文件内容代替。

我想大家对于<<多行重定向有些不理解,这里再对多行重定向在以例子说明一下。

[root@localhost ~]# tr a-z A-Z << end
> morning,boys
> today is another day
> please be happy
> end
MORNING,BOYS
TODAY IS ANOTHER DAY
PLEASE BE HAPPY

多行输入重定向后面需要接规定的结尾字符串,通常使用eof或end为结尾标示符。

多行输入重定向需要手动键入内容。单行输入重定向则需要跟文件或前一个命令的输出结果。



我知道看到这里依然会有点懵,下面通过9个实例来综合使用标准输出输入及管道命令

实验环境CentOS7.2


1、将/etc/issue文件中的内容转换为大写后保存至/test/issue#文件中

[root@localhost test]# cat /etc/issue | tr a-z A-Z > /test/issue1
[root@localhost test]# echo $(tr a-z A-Z < /etc/issue) > /test/issue2
[root@localhost test]# cat issue1
\S
KERNEL \R ON AN \M
[root@localhost test]# cat issue2
\S KERNEL \R ON AN \M

上面两种方式均可以实现要求,只不过输出格式略有不同,这根命令有关。在没有进一步的限制下,这两种表达方式均可。第一种使用管道,输出重定向,第二种使用命令引用,输入重定向及输出重定向。


2、将当前系统登录用户的信息转换为大写后保存至/test/t2文件中

[root@localhost test]# who | tr a-z A-Z > /test/t2
[root@localhost test]# cat t2
ROOT     :0           2016-08-02 10:12 (:0)
ROOT     PTS/0        2016-08-02 10:12 (192.168.85.1)
ROOT     PTS/1        2016-08-02 10:19 (192.168.85.1)


3、一个linux用户给root发邮件,要求邮件标题为”help”,邮件正文如下:

Hello, I am 用户名,the system version is here,pleasehelp me to check it ,thanks!

操作系统版本信息

我们使用用户gentoo

[root@localhost ~]# su gentoo
[gentoo@localhost /root]$ whoami
gentoo
[gentoo@localhost /root]$ cd /home/gentoo/
[gentoo@localhost gentoo]$ echo -e "Hello,I am `whoami`\nThe system version is here,please help me to check it ,thanks.\nThe version is `cat /etc/redhat-release`" | mail -s "help" root   
[gentoo@localhost gentoo]$ exit
exit
您在 /var/spool/mail/root 中有新邮件
[root@localhost ~]# mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/root": 3 messages 1 new
    1 gentoo@localhost.loc  Tue Aug  2 09:38  21/731   "help"
    2 root                  Tue Aug  2 09:44  21/741   "help"
>N  3 gentoo@localhost.loc  Tue Aug  2 19:37  20/737   "help"
& 3
Message  3:
From gentoo@localhost.localdomain  Tue Aug  2 19:37:36 2016
Return-Path: <gentoo@localhost.localdomain>
X-Original-To: root
Delivered-To: root@localhost.localdomain
Date: Tue, 02 Aug 2016 19:37:36 +0800
To: root@localhost.localdomain
Subject: help
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: gentoo@localhost.localdomain
Status: R
-e Hello,I am gentoo
The system version is here,please help me to check it ,thanks.
The version is CentOS Linux release 7.2.1511 (Core)

这里使用了命令替换来显示用户及版本信息,管道将第一个命令的输出递给下一个命令作为其输入。


4、将/root/下文件列表,显示成一行,并文件名之间用空格隔开

[root@localhost test]# ls -1 /root | tr '\n' ' '\n
anaconda-ks.cfg CST dead.letter file initial-setup-ks.cfg test.txt tr 公共 模板 视频 图片 文档 下载 音乐 桌面 [root@localhost test]#

上面命令已经满足我们的要求了,只不过不换行看着有些别扭,下面我们在完善下使其输出看着更舒服些。

[root@localhost test]# echo -e `ls -1 /root/ | tr '\n' ' '\n` 
anaconda-ks.cfg CST dead.letter file initial-setup-ks.cfg test.txt tr 公共 模板 视频 图片 文档 下载 音乐 桌面
[root@localhost test]#

使用echo的-e开启转义符使换行\n生效。


5、file1文件的内容为:”1 2 3 4 5 6 7 8 9 10” 计算出所有数字的总和

[root@localhost test]# cat > file1
1 2 3 4 5 6 7 8 9 10
^C
[root@localhost test]# cat file1 
1 2 3 4 5 6 7 8 9 10

先创建file1文件夹并输入题目要求内容。

[root@localhost test]# cat file1 | tr ' ' '+' | bc
55


6、处理字符串“xt.,l 1 jr#!$mn2 c*/fe3  uz4”,只保留其中的数字和空格

[root@localhost test]# echo 'xt.,l 1 jr#!$mn2 c*/fe3  uz4' | tr -cd '[:digit:][:space:]'
 1 2 3  4

这里使用了tr中的-c及-d补集跟删除,灵活使用补集概念可以更准确的帮助我们过滤不需要的信息。


7、将PATH变量每个目录显示在独立的一行

[root@localhost test]# echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost test]# echo ${PATH} | tr ':' '\n'
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/root/bin

这个题很简单只需要将PATH正确显示出来,使用tr将:替换为换行即可


8、删除指定文件的空行

这里我们创建一个含有很多空行的文本文件t9

[root@localhost test]# cat t9
q



ere
s



df
sd




sd
[root@localhost test]# cat t9 | tr -s '\n' 
q
ere
s
df
sd
sd

这里使用了tr的重复删除-s选项。


9、将文件中每个单词(字母)显示在独立的一行,并无空行

这里我们选择/etc/rc.d/rc0.d/K50netconsole文件,使用head查看下其文件前5行都什么内容

[root@localhost test]# head -5 /etc/rc.d/rc0.d/K50netconsole 
#!/bin/bash
# 
# netconsole    This loads the netconsole module with the configured parameters.
#
# chkconfig: - 50 50
[root@localhost test]# cat /etc/rc.d/rc0.d/K50netconsole | tr -cs '[:alpha:]' '\n' | head -5

bin
bash
netconsole
This

从结果来看我们实现了题目的要求,不过为什么第一行是空行,这是因为-s是将所有的空行压缩为一行,因此前面会留有一行空行。



本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
认真的测试过网上的大多数文章和版本,真正能一次性测试通过的文章太少了,需要反复的推敲,反复的查阅资料,才能真正的测试成功,所以,在此背景下,总结了Rsync,加上自己的理解分享出来; 1、 原理篇 Rsync,故名思议,是一个远程数据同步工具,可以镜像整个目录树和文件系统,也可以保持源文件的权限,时间和软硬链接,可以优化数据,文件重复数据的删除,也可以在LAN/WAN之间快速的同步多台主机的数据,这主要得益于Rsync的压缩和Rsync的核心算法,其算法,是本地和远程两台主机之间的文件达到同步并保持一致,

运维监控平台之ganglia - 2016-08-29 17:08:10

1、ganglia简介 Ganglia 是一款为 HPC(高性能计算)集群而设计的可扩展的分布式监控系统,它可以 监视和显示集群中的节点的各种状态信息,它由运行在各个节点上的 gmond 守护进程来采 集 CPU 、内存、硬盘利用率、 I/O 负载、网络流量情况等方面的数据,然后汇总到 gmetad 守护进程下,使用 rrdtool 存储数据,最后将历史数据以曲线方式通过 PHP 页面呈现。 Ganglia 的特点如下: 良好的扩展性,分层架构设计能够适应大规模服务器集群的需要 负载开销低,支持高并发 广
本文主要介绍zabbix在linux及windows下客户端的安装,网卡流量监控配置。 一、linux客户端安装 1. 编译软件 #useraddzabbix-s/sbin/nologin-M#./configure--prefix=/usr/local/zabbix-agent--enable-agent#makemakeinstall 2. 修改 agetn 配置 Server=127.0.0.1,192.168.115.31#本机即是agent和server127.0.0.1地址不可删除Server
通过定时执行python脚本,可以实现定期批量访问网站,如果发现网站打不开,第一时间发邮件到管理员邮箱进行预警 这里用的是python3.5 需要安装的插件: smtplib:发邮件需要用到 pycurl:访问网站时会需要用到 linecache:在读取txt网站清单时需要用到 具体思路: python程序从txt里面批量读取到网站的信息,通过Curl.py模拟浏览器去访问网站,并且把访问的结果写入到以自己的网站名称-日期.txt格式的文件中记录;有几种情况: 1、如果发现打不开了,直接发邮件提示网站已经
vSphere部署系列之09——HA和DRS群集管理 群集(Cluster)是将多台物理主机组织起来,群集管理其中所有主机的资源,形成一个大的资源池。群集中的所有的虚拟机可在池中的任意主机上自由移动,并且群集可做到快速扩容和HA故障冗余。群集的前提条件是要有共享存储,所有虚拟机及其配置文件必须驻留在共享存储器上。 在前面的博文章节中,已搭建了比较基础的实验环境,实现了vCenter对ESXi主机的管理,网络管理、共享存储管理。在这种情况下,各物理主机之间的计算资源(CPU、内存)是完全独立的,在某台主机出
昨天提交代码的时候自己的eclipse抽风了一下,发现自己的Web App Libraries里面的Jar包全部都不会自动加入到Web App Libraries中,导致之前配置的项目全都要重新手动配置,网上搜了一搜,找到了个解决方法: 参考链接http://blog.csdn.net/zhengzhb/article/details/6956130 定位到项目根目录中.settings里面的 org.eclipse.wst.common.component, 如下内容贴到里面保存一下,就能检测到WEB-

Linux NFS自动挂载autofs配置 - 2016-08-29 17:08:21

一、基于Linux下NFS文件系统的自动挂载方式, 前期准备环境两台Linux服务器: 准备一台NFS服务器端(系统环境centos6.5,ip地址192.168.100.100) 准备需要挂载NFS服务端的NFS客户端(系统环境centos6.5,ip地址192.168.100.101) 实施: 现在server端安装NFS保证能正常访问,我们这里通过yum工具安装即可 [root@nfsserver ~]# yum install nfs-utils rpcbind -y 通过修改NFS配置,共享/d
文本处理工具grep,正则表达式在Linux学习过程中很容易出现困惑与障碍的地方,这里分享下学习这方面内容的一些感受。 grep Global search REgular expression and Print out the line 作用:文本搜索工具,根据用户指定的‘ 模式(过滤条件) ’对目标文本逐行进行匹配检查;打印匹配到的行; ‘模式’:由 正则表达式 的元字符及文本字符所编写出的过滤条件。 grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [
HAProxy高可用负载均衡集群部署 基本信息: 系统平台:VMware WorkStation 系统版本: CentOS Linux release 7.2.1511 (Core) 内核版本: 3.10.0-327.el7.x86_64 集群架构: 前端:HAProxy 1、虚拟FQDN:www.simpletime.net 2、VIP:192.168.39.1;DIP:172.16.39.50 3、调度服务器:Varnish1、Varnish2 4、调度算法:URL_Hash_Consistent 5
常见的文件系统 Linux文件系统: ext2, ext3, ext4, xfs, btrfs, reiserfs, jfs, swap swap: 交换分区 光盘:iso9660 Windows:fat32, ntfs Unix: FFS, UFS, JFS2 网络文件系统:NFS, CIFS 集群文件系统:GFS2, OCFS2 分布式文件系统:ceph, moosefs, mogilefs, GlusterFS, Lustre 实验环境CentOS7.2 Linux根据其是否支持"journal"功