Linux运维学习历程-第六天-Linux重定向和管道

Linux运维学习历程-第六天-Linux重定向和管道

2

本章内容我们将学习linux中的重定向和管道两大用法

  I/O输入与输出设备

  重定向

  管道

  tee命令与tr命令

一、I/O设备

  1、什么是I/O设备

  管理和控制计算机的所有输入/输出(I/O)设备是操作系统的主要功能之一,主要分为字符设备和块设备。一般由机械和电子两个部分组成。

  功能介绍

  输入/输出(Input /Output ,简称I/O),指的是一切操作、程序或设备与计算机之间发生的数据传输过程。

  输入/输出系统(Input/Output System) ,指控制计算机数据流动的体制,包括程序、硬件。

  输入/输出设备,就是指可以与计算机进行数据传输的硬件。

  最常见的I/O设备有打印机、硬盘、键盘和鼠标。从严格意义上来讲,它们中有一些只能算是输入设备(比如说键盘和鼠标);有一些只是输出设备(如打印机)。

  所有储存器也可以算是输入/输出设备。如硬盘、软盘、光盘等。  

I/O设备分类

  现代计算机系统中配置了大量的外围设备,即I/O设备。依据它们的工作方式的不同,通常进行如下分类:

 (1)字符设备(character device),又叫做人机交互设备。用户通过这些设备实现与计算机系统的通信。它们大多是以字符为单位发送和接受数据的,数据通信的速度比较慢。例如,键盘和显示器为一体的字符终端、打印机、扫描仪、包括鼠标等,还有早期的卡片和纸带输入和输出机。含有显卡的图形显示器的速度相对较快,可以用来进行图像处理中的复杂图形的显示。

 (2)块设备(block device),又叫外部存储器,用户通过这些设备实现程序和数据的长期保存。与字符设备相比,它们是以块为单位进行传输的,如磁盘、磁带和光盘等。块的常见尺寸为512~32768B之间。

 (3)网络通信设备。这类设备主要有网卡、调制解调器等,主要用于与远程设备的通信。这类设备的传输速度比字符设备高,但比外部存储器低。这种分类的方法并不完备,有些设备并没有包括。例如,时钟既不是按块访问,也不是按字符访问,它所做的是按照预先规定好的时间间隔产生中断。但是这种分类足以使操作系统构造出处理I/O设备的软件,使它们独立于具体的设备。

 2、I/O设备作用的对象

 程序:指令+数据

      指令:一般由程序本身提供

      数据:I/O设备、文件、管道、变量等提供

  当然程序也可以理解为

      算法+数据结构

      只是分析的领域不同罢了。

 那么综上说,我们不难看出I/O设备在整个计算机系统中主要是对数据产生作用的,而我们在与计算机交互时的主要行为就是输入Input–>等待运算结果–>输出Output返回的值

      读入数据:Input

      输出数据:Output

 3、linux的I/O设备

   打开的文件都有一个FD:file descriptor(文件描述符),在linux中系统为程序提供了三种最常用的I/O设备

    标准输入(STDIN)-0   默认接受来自键盘的输入

    标准输出(STDOUT)-1  默认输出到终端窗口

    标准错误(STDERR)-2  默认输出到终端窗口

    0、1、2即为文件描述符 

  而在linux系统中I/O重定向既是:

    重新定义输入输出请求,改变默认位置,将其转向其它位置

二、重定向    

 Linux重定向

  1、输出重定向:     

     可以把标准输出和错误结果重新定向到其他文件(linux一切皆文件,包括硬件设备)

   STDOUT 和STDERR 可以被重定向到文件:

     命令 操作符号 文件名   

     支持的操作符号包括:

    >或1>  把STDOUT 输出重定向到文件,以正确结果覆盖原来的文件

    2>  把STDERR 输出重定向到文件,以错误结果覆盖原来的文件

     >!  把STDOUT 输出重定向到文件,以正确结果强制覆盖原来的文件

    &>  把所有输出重定向到文件,以所得结果覆盖原来文件

     2>&1 将一个标准错误输出重定向到标准输出 

         注释: 1代表 标准输出(在作用上和 &> 效果一样 而且顺序很重要,固定格式 )
     >&  将一个标准错误输出重定向到一个文件或设备 覆盖原来的文件( c-shell:csh)  

    注意:  >  会将文件原来的内容覆盖

    # set -C:  禁止将内容覆盖 已有文件, 但可追加

     强制覆盖:>!

    # set +C:  允许覆盖

   >> 原有内容基础上,追加输出的内容

   () :合并多个程序的STDOUT

     例如:( cal 2007 ; cal 2008 ) > all.txt

   可以利用> 文件名 >> 文件名来重建空文件,效果等同 touch 文件名

   建议使用>> 文件名,因为可以防止误操作覆盖已有文件的数据

      2、输入重定向

           可以把标准输入重新定向到其他文件(linux一切皆文件,包括硬件设备)

           STDIN 重新定向到文件

          命令  文件名  操作符号

           支持的操作符号包括:

          <或0<   把STDIN输入重定向到文件,覆盖原来的文件

          << 把STDIN输入重定向到文件,追加新文件内容到文件

        注意:正常标准输入0的默认设备是鼠标、键盘;而  < 可以将文件中的内容输入到其他文件,所以说输入重定向

                  使用“<< 终止词”命令从键盘把多行重导向给STDIN,直到“<<终止词” 位置的所有文本都发送给STDIN;有时被称为就地文本(heretext)

  示例1:

 cat命令

1
cat

结果wKioL1egCYjTFTGWAAA38_OZT1g768.jpg

从键盘标准输入什么,返回到标准输出的终端就是什么

1
cat test.txt

     wKioL1egC6yRUuw2AAA1IoX5e04757.jpg

    从文件中输入的内容

1
2
cat > stdout.txt < test.txt
cat stdout.txt

wKioL1egDLnQdVWdAABGMDzh358945.jpg    示例2:

1
2
3
4
5
mail -s hello NameLess <<end      #这里回车输入以下内容
> hello,I am root,
> I hope we can talk face to face,
> please find me before work today.
> end

wKioL1egDrfTOGeTAAB37g_HQ4I344.jpg   注意:<<结束字符   是成对出现的,开始字符是什么,结束字符就是什么,而且必须是单独一行出现才有效。 

    示例3:

1
2
3
4
1 > stdout.txt
'1' > stdout.txt
"1" > stdout.txt
`1` > stdout.txt

wKioL1egECeTUH_3AACcYxmSrwU680.jpg

注意:此种重定向无效,个人分析,单纯的字符是没有数据输出”动作“,所以无法将内容送达文件,虽然存在 > file或 >> file 来重建空文件,可以理解为将”空“定向到file中,不存在则创建了空文件,但是和上面操作不能一概而论

         而且当我们输入完数据后,输入动作结束,数据就是存储在内存(存储设备)中,既不在硬盘(I/O设备)上,也不是键盘(I/O设备)直接输入的,所以不是输入输出,也就不能用重定向啦

         此处仅个人理解,如有更专业的解释,还望各路大神指点


总结:

          重定向是针对输入输出数据的,所以可以理解为基于I/O设备的操作过程,才能用到重定向

           默认键盘(I/O设备)输入数据给命令       我们给它重定向 < 从硬盘(I/O设备)存储的文件输入数据给命令

           默认终端(I/O设备)输出数据给用户      我们给它重定向 > 到硬盘(I/O设备)存储的文件中,也可以是/dev/tty1-60这些终端中

三、管道

        1、进程

           在学习管道之前,我们先了解一下”进程“以便我们更好的理解管道的含义和作用

           进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。            

    狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。

    广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。

进程的概念主要有两点:第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。 

    进程是操作系统中最基本、重要的概念。是多道程序系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各道程序的活动规律引进的一个概念,所有多道程序设计操作系统都建立在进程的基础上。    

   原因

    操作系统引入进程的概念的原因:

    从理论角度看,是对正在运行的程序过程的抽象;

    从实现角度看,是一种数据结构,目的在于清晰地刻画动态系统的内在规律,有效管理和调度进入计算机系统主存储器运行的程序。

   特征

    动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。

    并发性:任何进程都可以同其他进程一起并发执行

    独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;

    异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进

    结构特征:进程由程序、数据和进程控制块三部分组成。

    多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;但是执行过程中,程序不能发生改变。

           2、管道与进程

                        以上就是进程的基本含义,我们说到了进程,就要说管道;

                管道的作用:

                       主要用于进程间通信,能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息。可以组合多种工具的功能。

                      进程间通信主要包括管道, 系统IPC(包括消息队列,信号,共享存储), 套接字(SOCKET).

                管道的种类                       

    管道包括三种:

    1)普通管道PIPE, 通常有两种限制,一是单工,只能单向传输;二是只能在具有亲缘关系的进程,比如父子或者兄弟进程间使用.

    2)流管道s_pipe: 去除了第一种限制,为半双工,可以双向传输.

    3)命名管道:name_pipe, 去除了第二种限制,可以在许多并不相关的进程之间进行通讯.

     在此篇中我们学习的管道普通管道PIPE,是一种常见管道,所以以下简称为管道了

             管道PIPE定义解析:

                   单工:支持数据单方向传输,也就是说只能向一个方向传递数据不能反向传递。(有数据信息传输,网络等基础的可以跳过)

                   具有亲缘关系:这个初学者并不好理解,现在我也并不是有太专业的概念,我的理解其实也很简单,就是进程之间必然有着直接关系,就比如我们用linux时,其实都在一个shell类型(默认为bash)下,所以我们在平时所有的命令看似没关系,其实基本上都是兄弟,shell的子进程;当然这是我初步的理解,很片面;但是我们只要知道,普通管道PIPE是两个具有亲缘关系的进程才能使用的一种进程通信方式。

                 在linux命令行中用符号“ | ”代表管道 ,并连接命令

                格式:COMMAND1 |COMMAND2 |COMMAND3 …

                管道是对标准输入输出来说的,对于错误结果可以 2>&1 |    或者 |&   可以将标准输出错误重定向到后面命令

                格式含义:有COMMAND1命令执行后的stdout通过管道 | 传递给COMMAND2作为其stdin数据(参数),依次类推。相当于前一个命令的标准输出变为后一个命令的标准输入   进行了两次重定向

               注意:默认正常情况下命令执行的错误结果不能通过管道转发,但可以利用2>&1或|&实现

    总结:综上所述,管道用于进程间通信的,而进程是程序的实体,动态程序的抽象化

              所以我们理解为在linux中管道主要用于命令与命令之间通信的,这规定了管道的使用条件。也解释了为什么管道不能直接作用于目录(也就是路径)和文件。

 四、tee命令与tr命令        

        tee命令执行过程可以理解为如图:

   数据输入(键盘、管道传递的数据等)——>tr——>数据输出(文本文件等)

                                                                                         |

                                                                                         |

                                                                                        ∨

                                                                                   终端显示        


tee:将数据重定向到文件,另一方面还可以提供一份重定向数据的副本作为后续命令的stdin。简单的说就是把数据重定向到给定文件和屏幕上。 

       存在缓存机制,每1024个字节将输出一次。若从管道接收输入数据,应该是缓冲区满,才将数据转存到指定的文件中。若文件内容不到1024个字节,则接收完从标准输入设备读入的数据后,将刷新一次缓冲区,并转存数据到指定文件。

      tee [OPTION]… [FILE]…

            -a:向文件中重定向时使用追加模式; 

            -i:忽略中断(interrupt)信号。


tr:翻译转意或删除字符

     tr [OPTION]… SET1 [SET2]

           从标准输入中替换、缩减和/或删除字符,并将结果写到标准输出。

            -c, -C, –complement       首先补足SET1即除了SET1的其它

            -d, –delete            删除匹配SET1 的内容,并不作替换

            -s, –squeeze-repeats      如果匹配于SET1 的字符在输入序列中存在连续的

                                重复,在替换时会被统一缩为一个字符的长度

            -t, –truncate-set1        先将SET1 的长度截为和SET2 相等

      SET 是一组字符串,一般都可按照字面含义理解。解析序列如下:

              \NNN    八进制值为NNN 的字符(1 至3 个数位)

              \\        反斜杠

              \a        终端鸣响

              \b        退格

              \f        换页

              \n        换行

              \r        回车

              \t        水平制表符

              \v        垂直制表符

           字符1-字符2    从字符1 到字符2 的升序递增过程中经历的所有字符

           [字符*]    在SET2 中适用,指定字符会被连续复制直到吻合设置1 的长度

           [字符*次数]    对字符执行指定次数的复制,若次数以 0 开头则被视为八进制数

           [:alnum:]    所有的字母和数字

           [:alpha:]    所有的字母

          [:blank:]    所有呈水平排列的空白字符

          [:cntrl:]    所有的控制字符

          [:digit:]    所有的数字

          [:graph:]    所有的可打印字符,不包括空格

          [:lower:]    所有的小写字母

          [:print:]    所有的可打印字符,包括空格

          [:punct:]    所有的标点字符

          [:space:]    所有呈水平或垂直排列的空白字符

          [:upper:]    所有的大写字母

          [:xdigit:]    所有的十六进制数

          [=字符=]     所有和指定字符相等的字符

   注意:

      仅在SET1 和SET2 都给出,同时没有-d 选项的时候才会进行替换。

      仅在替换时才可能用到-t 选项。如果需要SET2 将被通过在末尾添加原来的末字符的方式补充到同SET1 等长。SET2 中多余的字符将被省略。只有[:lower:] 和[:upper:]以升序展开字符;在用于替换时的SET2 中以成对表示大小写转换。-s 作用于SET1,既不替换也不删除,否则在替换或展开后使用SET2 缩减。

           示例1

                 将/etc/issue文件中内容转换成大写字母输出

1
tr 'a-z' 'A-Z'/etc/issue

          示例2

                 删除/testdir/test.txt文件中的所有abc 中任意字符(分区和文件都是我自己建的不是linux默认的)

1
tr -d abc < /testdir/test.txt

          示例3

                   将test.txt文件中的内容输入重定向到cat命令然后输出重定向大stdout.txt中

1
cat > stdout.txt <test.txt

         示例4

                  一页一页的查看/etc的内容

1
ls -l /etc |less

         示例5

                   把输入发送给打印机

1
echo "test print" |lpr -P printer_name

原创文章,作者:NameLess,如若转载,请注明出处:http://www.178linux.com/28146