主要概念:
1.基于终端的程序往往从一个源读取信息,向一个目的地写入信息;
2.程序读取的源被称为标准输入(简称为stdin),通常与终端键盘连接;
3.程序写入的目的地被称为标准输出(简称为stdout),通常与终端显示器相连;
4.使用bash Shell时,可以用>或>>重定向标准输出,用<重定向标准输入;
许多Linux命令从键盘读取输入,向终端显示输出。一个命令的输出可以用作另一个命令的输入,从而可以同时使用多个简单的命令来执行更复杂的任务。
三种类型的程序:
1.图形程序
图形程序是为在X图形环境中运行设计的。它们希望用户使用鼠标,并且使用常用的图形组件,如弹出菜单和按钮作为用户输入。Firefox网络浏览器就是一种图形程序。
2.屏幕程序
基于屏幕的程序使用文本控制台。它们利用整个屏幕熟练地处理文本定位和屏幕刷新。它们不需要鼠标,因此适用于终端盒虚拟控制台。vi和nano文本编辑器以及links网络浏览器都属于屏幕程序。
3.终端程序
终端程序以流的形式聚集输入和显示输出,很少刷新屏幕,终端程序以其简明的特点经常被简单地称作命令。ls、grep和useradd属于终端程序。
例如:
1.用户elvis使用的机器变得非常缓慢,为了诊断问题,elvis想检查当前运行的进程,但是由于机器反应很慢,他现在先搜集信息,之后再做分析,他把ps aux命令的输出重定向到文件pusaux.txt文件中,当机器反应快时再回头检查这个文件。
[root@host2 tmp]# ps aux > /tmp/sluggish.txt
2.elvis现在不仅想要收集进程信息,还要记录电脑出现反应迟钝情况时的时间戳
[root@host2 tmp]# date > psaux.txt | ps aux >> sluggish.txt [root@host2 tmp]# head sluggish.txt Wed Nov 5 19:07:00 CST 2014 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.1 0.1 19352 1536 ? Ss 18:50 0:01 /sbin/init root 2 0.0 0.0 0 0 ? S 18:50 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S 18:50 0:00 [migration/0] root 4 0.0 0.0 0 0 ? S 18:50 0:00 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S 18:50 0:00 [migration/0] root 6 0.0 0.0 0 0 ? S 18:50 0:00 [watchdog/0] root 7 0.1 0.0 0 0 ? S 18:50 0:01 [events/0] root 8 0.0 0.0 0 0 ? S 18:50 0:00 [cgroup]
3.用户elvis用基于终端的mail命令从键盘上给管理员写了一封电子邮件。mail命令把收件人当做一个参数,主题行可以用-s命令行选项指定,然后从键盘上键入邮件正文,另起一行上单独写一个英语的句号,标志着邮件正文结束。
[root@host2 /]# mail -s "Computer is sluggish" sysadmin@example.com Hey sysadmin: I'm sending a list of processes that were running when the computer was running in a separate email. Thanks! --elvis . EOT
作为后续回复信息,用户elvis可以将记录在文件sluggish.txt中的ps命令输出发送出去,他只需重定向mail命令的标准输入流,使之从文件中读取就可以了。
[root@host2 tmp]# mail -s "ps output" sysadmin@example.com < sluggish.txt
【透过表象看本质:打开文件盒文件描述符】
为了全面理解进程如何管理标准输入、标准输出和文件,我们必须引入文件描述符(file descriptor)这一概念。要从文件读取信息或向文件写入信息,进程必须打开这个文件。Linux/Unix进程通过给每个当前被他们打开的文件赋整数值来追踪这些文件,这个整数被称作文件描述符。
Linux内核提供了一个简单的方法,用/proc文件系统来检查当前运行进程打开的文件和文件描述符。每个进程在/proc下有一个相关的子目录,以其进程ID命名。进程的子目录里有一个叫做fd(file descriptor)的子目录。在/proc/pid/fd子目录中,进程打开的每个文件都有一个符号连接。符号连接的名称是打开文件的整数文件描述符,符号连接解析到被打开文件本身。
例子:
ftp和gnuplot程序都是复杂的程序,因此这几个例子仅仅介绍了与本节主题相关的程序功能:如果程序是从命令行界面上驱动的,通常可以用简单的文本输入和重定向自动驱动这个程序。
1.走出sort命令的困惑
用户使用sort命令对文本文件zoo中的动物进行排序;
[root@host2 tmp]# ls zoo [root@host2 tmp]# cat zoo elephant seal ape giraffe fish [root@host2 tmp]# sort zoo ape elephant fish giraffe seal [root@host2 tmp]# sort < zoo ape elephant fish giraffe seal
sort命令(以最简单的形式)读取文件,并写入按字母顺序逐行分类的内容。像cat命令一样,当没有提供任何参数时,sort命令将标准输入作为它的输出。
[root@host2 tmp]# sort ls quit man sort exit get me out of this exit get me out of this ls man sort quit
2.用户想用简单的方法生成机器CPU活动图。他对vmstst命令很熟悉,这个命令可以对设计系统性能许多参数进行抽样并制成表格,这个命令采用两个数字参数:
第一个指定了抽样时间(以秒为单位);
第二个指定了要采集的样本数;
他对后三列很感兴趣,这三列是CPU在用户(us)、系统(sy)和空闲(id)状态上所花的时间百分比。他从机器上采集了60秒的数据,抽样检查每秒钟的数据。
[root@host2 tmp]# vmstat 1 60 > stats.txt [root@host2 tmp]# head stats.txt procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 0 0 0 256156 74520 257560 0 0 38 9 43 73 0 0 99 1 0 0 0 0 256140 74520 257592 0 0 0 0 27 50 0 0 100 0 0 0 0 0 256140 74520 257592 0 0 0 0 29 48 1 0 99 0 0 0 0 0 256140 74520 257592 0 0 0 0 22 40 0 0 100 0 0 2 0 0 256140 74520 257592 0 0 0 0 25 53 0 0 100 0 0 0 0 0 256140 74520 257592 0 0 0 0 25 49 0 1 99 0 0 1 0 0 256140 74528 257592 0 0 0 56 30 55 1 0 99 0 0 1 0 0 256132 74528 257592 0 0 0 88 48 57 0 2 98 0 0
由于前两行文本影响了数据图,用户在文本编辑器中打卡文件stats.txt,轻而易举地把它们删除了。
为了绘制数据图,她使用了gnuplot命令,这是一个复杂的绘图软件包,使用从终端界面读取的命令来生成数学函数和数值数据图。浏览了gnuplot在线帮助后,她用下列命令绘制数据图,生成了一个叫做cpu.png的PNG制图文件。
#gnuplot gnuplot>set term png gnuplot>set output 'cpu.png' gnuplot>plot 'stats.txt' using 0:13 title "user" with lines,'stats.txt' using 0:14 title "system" with lines,'stats.txt' using 0:15 title "idle" with lines gnuplot>quit
退出gnuplot命令后,他返回到bash shell,用ego图像浏览器查看数据图,如图所示:
由于他想经常生成类似的图,而且不想每次都痛苦地敲gnuplot的绘图命令,于是他生成了一个可以用来自动运行gnuplot的脚本,编辑了一个文件cpu_plot.gnuplot,其中包含了所有敲入gnuplot命令:
#cat cpu_plot.gnuplot set term png set output 'cpu.png' plot 'stats.txt' using 0:13 title "user" with lines,'stats.txt' using 0:14 title "system" with lines,'stats.txt' using 0:15 title "idle" with lines
现在,他将脚本重定向为gnuplot标准输入来方便地绘制新采集的数据:
#gnuplot < cpu_plot.gnuplot
标准输入、标准输出和错误输出的文件描述流:
数据流 描述符 缩写
标准输入 0 stdin
标准输出 1 stdout
标准错误 2 stderr
【重定向】
>输出重定向,覆盖掉原有内容;称为覆盖输出
<输入重定向
>>追加输出,在原文后追加输入内容
<<在此处生成文档(here document)
set -C禁止对已经存在的文件使用覆盖重定向
强制覆盖输出,则使用 >|
set +C关闭上述功能
2>重定向错误输出
2>>追加方式重定向错误输出
&>重定向标准输出或错误输出至同一个文件(输出所有)
-----bash中重定向标准输入、标准输出和标准错误一览表-----
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中(方便的语法)
【用/dev/null过滤标准错误】
find /var -user elvis 2> /tmp/tmp find /var -user elvis 2> /dev/null
因为elvis的权限有限,var下面的目录中与用户elvis有关的子目录就显示出来,但更多是保所有权限拒绝的错误信息,因此要筛选错误;
第一种方法虽然过滤了错误信息,但却多了个用户并不想要的tmp文件,因此采用了第二种方法过滤;
在这种情况下,当用户想抛弃信息流时,有经验的Unix用户通常会把输出重定向到一个叫做/dev/null的伪设备中。
/dev/null是一个字符设备节点,就像用在约定的设备驱动中的节点一样。
当用户写入/dev/null时,信息只会被内核抛弃,当用户从/dev/null读取时,他们会很快读完文件。注意,RHEL默认配置下,/dev/null是少数几个普通用户有写入权限的文件之一。
ls /varr > /tmp/var1.out 2> /tmp/var2.out
如果正确就输出到var1.out,如果错误就输出到var2.out
END有时候也用EOF(End of File)
[root@host2 tmp]# cat << END > the first line. > the second line. > END the first line. the second line. [root@host2 tmp]# cat >> /tmp/file.txt << EOF > the first line. > the second line. > EOF [root@host2 tmp]# ls file.txt [root@host2 tmp]# cat file.txt the first line. the second line.