1.tee多重定向

tee [options] FILE1 FILE2 FILE3...

tee的作用是将一份标准输入多重定向,一份重定向到标准输出/dev/stdout,然后还将标准输入重定向到每个文件FILE中。

例如:

$ cat alpha.log | tee file1 file2 file3 | cat
$ cat alpha.log | tee file1 file2 file3 >/dev/null

上面第一个命令将alpha.log的文件内容重定向给file{1..3}和标准输出通过管道传递给cat;

上面第二个命令将alpha.log的文件内容重定向给file{1..3}和/dev/null。

tee重定向给多个命令

写多了脚本的人可能遇到过这样一种需求:将一份标准输入,重定向到多个命令中去。大概是这样的:

                      | CMD1

INPUT | tee

| CMD2

其实bash自身的特性就能实现这样的需求,通过重定向到子shell中,就能模拟一个文件重定向行为:

cat alpha.txt | tee >(grep -E "a|b") >(grep -E "d|b|c")

(实际上这里的两个>(cmd_list)不是重定向,而是进程替换。命令行解析开始时,将首先进行进程替换,这两个grep将等待标准输入。然后启动cat和tee,然后tee将标准输出交给两个进程的标准输入)

上面的命令将alpha.txt文件内容重定向为3份:一份给第一个grep命令,一份给第二个grep命令,一份给标准输出。假如alpha.txt的内容是a b c d e5个字母分别占用5行(每行一个字母),上面的输出结果如下:

a
b
c
d
e # 前5行是重定向到/dev/stdout的
a
b # 这2行是重定向给第一个grep后的执行结果
b
c
d # 这3行是重定向给第二个grep后的执行结果

如果不想要给标准输出的那份重定向,加上>/dev/null

cat alpha.txt | tee >(grep -E "a|b") >(grep -E "d|b|c") >/dev/null

tee重定向给多个命令时的问题

但是必须注意,tee将数据重定向给不同命令时,这些命令是独立执行的,它们都会各自打开一个属于自己的STDOUT,如果它们都重定向到标准输出,由于涉及到多个不同的/dev/stdout,它们的结果将出现两个问题:

  1. 不保证有序性
  2. 因为跨了命令,交互式模式下(默认标准输出为屏幕)可能会出现命令行隔断的问题(非交互式下不会有问题)

例如:

$ cat alpha.txt | tee >(grep -E "a|b") >(grep -E "d|b|c") >/dev/null
$ a # 结果直接出现在提示符所在行
b
b
c
d $ cat alpha.txt | tee >(grep -E "a|b") >(grep -E "d|b|c") >/dev/null
b
c # 这次的结果和上次的顺序不一样
d
a
b

这两个问题,在写脚本过程中必须解决。

对于第二个问题:不同/dev/stdout同时输出时在屏幕上交叉输出的问题,只需将它们再次重定向走即可,这样两份不同的/dev/stdout都再次同时作为一份标准输入:

$ cat alpha.txt | tee >(grep -E "a|b") >(grep -E "d|b|c") >/dev/null | cat

对于第一个问题:不同/dev/stdout同时输出时,输出顺序的随机性,这个没有好方法,只能在各命令行中将各自的结果保存到文件中:

$ cat alpha.txt | tee >(grep -E "a|b" >file1) >(grep -E "d|b|c" >file2) >/dev/null

所以,tee在重定向到多个命令中是有缺陷的,或者说用起来非常不方便,只要将各命令的结果各自保存时,才能一切按照自己的预期进行。那么,pee登场了,多重定向非常好用的一个命令。

2.pee代替tee

pee是moreutils包中的一个小工具,先安装它(epel源中有):

yum -y install moreutils

在man pee中,pee的作用是将标准输入tee给管道。语法:

pee ["cmds"]

不是很好理解,可以通过几个示例直接感受它的用法。

$ cat alpha.txt | pee 'grep -E "a|b"' 'grep -E "d|b|c"'
a
b
b
c
d

所以,它的基本用法是pee "CMD1" "CMD2"

如果想将结果保存到文件,只需加一个命令即可,例如下面的cat >myfile

$ cat alpha.txt | pee 'grep -E "a|b"' 'grep -E "d|b|c"' 'cat >myfile'

和tee有同样的问题,如果各命令都没有指定自己的标准输出重定向,它们将各自打开一个属于自己的/dev/stdout,同样会有多个/dev/stdout同时输出时结果数据顺序随机性的问题,但是不会有多个/dev/stdout同时输出时交互式的隔断性问题,因为pee会收集各个命令的标准输出,然后将收集的结果作为自己的标准输出

pee和tee最大的不同,在于pee将来自多个不同命令的结果作为pee自己的标准输出,所以下面的命令是可以像普通命令一样进行重定向的。

INPUT | pee CMD1 CMD2 >/FILE

而tee则不同,是将cmd1和cmd2的结果放进标准输出(假设各命令自身没有使用重定向),保存到FILE中的是tee读取的标准输入。

INPUT | tee >(cmd1) >(cmd2) >/FILE

所以,想要重定向tee中cmd1和cmd2的总结果,必须使用额外的管道,或者将整个tee放进子shell。

INPUT | tee >(cmd1) >(cmd2) >/dev/null | cat >FILE1
INPUT | ( tee >(cmd1) >(cmd2) >/dev/null ) >/FILE1

Linux tee的花式用法和pee的更多相关文章

  1. linux tee 命令详解

    man tee: NAME tee - read from standard input and write to standard output and files SYNOPSIS tee [OP ...

  2. Linux tee命令详解

    Linux tee命令 Linux tee命令用于读取标准输入的数据,并将其内容输出成文件.如果文件指定为"-",则将输入内容复制到标准输出 tee指令会从标准输入设备读取数据,将 ...

  3. [转]linux tee 命令详解

    转自: http://codingstandards.iteye.com/blog/833695 用途说明 在执行Linux命令时,我们可以把输出重定向到文件中,比如 ls >a.txt,这时我 ...

  4. linux系统man命令用法和安装方法

    Linux提供了丰富的帮助手册,当你需要查看某个命令的参数时不必到处上网查找,只要man一下即可. Linux的man手册共有以下几个章节: 代號 代表內容 1 使用者在shell中可以操作的指令或可 ...

  5. Linux下安装Scim-googlepinyin输入法和设置Sublime Text中文输入

    1.安装git sudo apt-get install git http://www.cnblogs.com/perseus/archive/2012/01/06/2314069.html 2.获取 ...

  6. linux tee

    tee 功能说明:读取标准输入的数据,并将其内容输出成文件. 语 法:tee [-ai][--help][--version][文件...] 补充说明:tee指令会从标准输入设备读取数据,将其内容输出 ...

  7. Linux tee命令

    一.简介 tee以标准输入作为输入,标准输出和文件作为输出.   二.语法 Usage: tee [OPTION]... [FILE]... Copy standard input to each F ...

  8. Linux tee命令使用详解分享

    tee命令主要被用来向standout(标准输出流,通常是命令执行窗口)输出的同时也将内容输出到文件,下面是tee的man 信息 read from standard input and write ...

  9. Linux和Shell回炉复习系列文章总目录

    本页内容都是本人回炉Linux时整理出来的.这些文章中,绝大多数命令类内容都是翻译.整理man或info文档总结出来的,所以相对都比较完整. 本人的写作方式.风格也可能会让朋友一看就恶心到直接右上角叉 ...

随机推荐

  1. web页面font-family显示

    font-family属性很简单,直接写在css或style样式中即可. 如: font-family: "Microsoft YaHei"; 但是如果希望电脑能正确的显示我们设置 ...

  2. spring InitializingBean和DisposableBean init-method 和destroy-method @PostConstruct @PreDestroy

    对于初始化函数: @PostConstruct 注解的方法 InitializingBean接口定义的回调afterPropertiesSet() Bean配置中自定义的初始化函数 对于析构则与上相同 ...

  3. dhcp服务简单配置

    dhcp服务搭建 注意事项: > 配置虚拟机虚拟网络编辑器,取消"使用本地DHCP服务将IP地址分配给虚拟机" > 虚拟机网络连接设置为"仅主机模式" ...

  4. MapGIS DataStore

    http://www.mapgis.com/index.php/index-show-tid-206.html 异构数据同时加载 DCServer感觉已经集成到 IGServer中了. >> ...

  5. 如果解决小程序1024kb渲染之坑

    问题: 在小程序开发中如果有那么个场景和操作步骤,获取商品下拉列表商品列表data为goodsList 当从后台获取数据response.data.list,通常我们会setData({goodsLi ...

  6. 与Servlet相关的类

    有4个有关的类,通过servlet可以获得其中的三个,然后通过ServletConfig间接获取ServletContext.1. ServletConfig该类是在Servlet容器初始化Servl ...

  7. Openvswitch手册(2): OpenFlow Controller

         我们这一节主要来看Controller Controller有两种: Primary Controller: 真正控制vswitch的flow table,vswitch会保持和contro ...

  8. 搭建servlet+jsp环境

    c3p0: <?xml version="1.0" encoding="UTF-8"?><c3p0-config> <named- ...

  9. 转载:Package by feature, not layer

    原文地址:Package by feature, not layer Package by feature, not layer The first question in building an a ...

  10. PMS权限管理和鉴权过程

    一.权限的管理基础知识 1.系统的权限机制分为:权限解析.权限分配.鉴权.动态添加权限 2.PermissionInfo :  PackageParser.Permission中包含一个对应的Perm ...