- 连续指令的下达方式:
这里需要再提几个重要的信息,我们刚刚上面提过说,两个指令先后写在一起,可以这样写:
- command1; command2
利用分号『 ; 』来分隔,这个分号的意思,代表不论 command1 执行结果为何,command2都会被执行!那么如果我是两个相关的指令,第一个 command1 如果执行结果有错误,第二个就不被执行,可以这样做吗?当然可以,就使用下面两个连结的咚咚:
- command1 && command2
command1 || command2
还记得我们之前的变量内容中,那个 ? 代表什么吗?没错,就是代表前一个执行的指令内容有没有错误,如果有错误就回传为1 ,没有错误就回传为 0 ,你可以经由 echo $? 来查询得知!那么 &&就是代表,当 command1 执行结果传回值为 0 的时候,也就是没有错误讯息时,则command2 才会开始执行,而 || 恰恰相反,当 command1 有错误讯息时, command2才会执行!举个例子来说,我的系统中并没有 /vbird 这个目录,所以执行 ls /vbird应该会有错误讯息才对,所以,底下三个指令串会显示什么呢?
[root @testroot]# ls /vbird ; ls /
[root @testroot]# ls /vbird && ls /
[root @testroot]# ls /vbird || ls /试看看呦!
- 基本上,这个子题是 bash 相当重要的观念,这里可得花点心思才行呦!
- 什么是『重导向, redirect ?』:简单的说,就是将你目前的所得资料转到其它地方去就是了!例如我们常用的,将目前的屏幕输出数据转到档案中去,就可以这么写:『ls-l / > test 』,那个大于的符号『 > 』就是将输出结果导向到test 这个档案中的意思啰!这个时候:
- 如果你执行『 ls -l / 』而已的话,屏幕会将根目录的档案与目录都列出在屏幕上;
- 但是当使用 > 导向到 test 这个档案中时,则屏幕不会显示任何讯息,但是会将刚刚你执行的结果输出到test 这个档案中。
-
所以啰,你只要『 vi test 』一下,就会知道 test 这个档案中记录了刚刚我们执行的数据结果啰!不过,这里需要特别留意的是,当你使用> 符号将数据由屏幕导向到档案中时,则:
- 该档案(就是 test )若不存在,系统会自动的将他建立起来,但是,
- 当这个档案存在的时候,那么系统就会先将这个档案内容清空,然后再将数据写入!
- 也就是若以 > 输出到一个既存盘案中,呵呵,那个档案就会被覆盖掉啰!
-
所以啰,你只要『 vi test 』一下,就会知道 test 这个档案中记录了刚刚我们执行的数据结果啰!不过,这里需要特别留意的是,当你使用> 符号将数据由屏幕导向到档案中时,则:
- 除了这个 > 的符号之外,在 bash 命令执行的过程中,主要有三种输出入的状况,分别是:
- 标准输入;代码为 0 ;或称为 stdin;使用的方式为 <
- 标准输出:代码为 1 ;或称为 stdout;使用的方式为1>
- 错误输出:代码为 2 ;或称为 stderr;使用的方式为2>
-
基本的指令书写方式为:
指令 1>
1>>
2>
2>>
<装置或档案 左边一定是指令,至于右边则可能是装置或者是档案!注意了!那个1> 与 2> 之间并没有空格符!而相关的使用说明可以举例如下:
[test @testtest]# ls -al > list.txt
将显示的结果输出到list.txt 档案中,若该档案以存在则予以取代!
[test @testtest]# ls -al >> list.txt
将显示的结果累加到list.txt 档案中,该档案为累加的,旧数据保留!
[test @testtest]# ls -al 1> list.txt 2> list.err
将显示的数据,正确的输出到list.txt 错误的数据输出到 list.err
[test @testtest]# ls -al 1> list.txt 2>&1
将显示的数据,不论正确或错误均输出到list.txt 当中!
[test @testtest]# ls -al 1> list.txt 2> /dev/null
将显示的数据,正确的输出到list.txt 错误的数据则予以丢弃!
注意!错误与正确档案输出到同一个档案中,则必须以上面的方法来写!
不能写成其它格式!这个观念相当的重要,尤其是在 /etc/crontab 当中执行的时候,如果我们已经知道错误的讯息为何,又不想要让错误的讯息一直填满root 的信箱,就必须以 2> 搭配 /dev/null 这个垃圾桶黑洞装置,来将数据丢弃!这个相当的重要!
-
这里我们来说明一下命令重导向里面几个常用的符号与装置:
- < :由 < 的右边读入参数档案;
- > :将原本由屏幕输出的正确数据输出到> 右边的 file ( 文件名称 ) 或 device ( 装置,如 printer )去;
- >> :将原本由屏幕输出的正确数据输出到>> 右边,与 > 不同的是,该档案将不会被覆盖,而新的数据将以『增加的方式』增加到该档案的最后面;
- 2> :将原本应该由屏幕输出的错误数据输出到2> 的右边去。
- /dev/null :可以说成是黑洞装置!
好了,对于『 > , >> 』这两个东西有一定的概念之后,我们来深入的谈一谈『命令输出重导向』的观念吧!如前所述,基本上,Linux 执行的结果中,可以约略的分成『 正确输出』与『 错误输出』两种方式。例如,当你以一般身份执行find 这个指令时,例如执行『 find/ -name testing 』时,由于你是一般身份,又有些数据夹是不允许一般身份者进入的,所以啰,当你使用find 时,就会有错误讯息发生了!但同时如果有 testing 这个档案在你可以进入的资料夹当中,那么屏幕也会输出到给你看!因此,就具有正确的与错误的输出两种啰!(分别称为Stdout 与 Stderror)例如下面为执行结果:里面的『 find: /home/root: Permissiondenied 』就告诉你该数据夹你没有权限进入,这就是错误的输出了,那么『 /home/test/tseting』就是正确的输出了!
[test @testtest]# find / -name testing
find: /home/test1:Permission denied <==这是错误的输出
find: /home/root:Permission denied <==这是错误的输出
find: /home/masda:Permission denied <==这是错误的输出
/home/test/testing <==这是『正确』的输出
[test @testtest]#好了,那么假如我们想要将数据输出到 list 这个档案中呢?执行『 find /-name testing > list 』会有什么结果?呵呵,你会发现 list里面存了刚刚那个『正确』的输出数据,至于屏幕上还是会有错误的讯息出现呢!伤脑筋!如果想要将正确的与错误的数据分别存入不同的档案中需要怎么做?!呵呵!其实在数据的重导向方面,正确的写法应该是『1> 』与『 2> 』才对!但是如果只有 > 则预设是以 1> 来进行数据的!那个 1>是输出正确数据, 2> 则是错误数据输出项目。也就是说:
好了,那么上面的例子中,我们如何将数据输出到不同的地方去呢?可以这么写:
- 1> :是将正确的数据输出到指定的地方去
- 2> :是将错误的数据输出到指定的地方去
[test @testtest]# find / -name testing 1> list_right 2> list_error 这样一来,刚刚执行的结果中,有 Permission 的那几行错误信息都会跑到 list_error这个档案中,至于正确的输出数据则会存到 list_right 这个档案中啰!这样可以了解了吗?如果有点混乱的话,去休息一下再来看看吧!!
-
再来,如果我只要正确的数据,错误的信息我不要了呢?呵呵,这个时候
/dev/null 这个垃圾桶就很重要了!
/dev/null是什么呢?基本上,那就有点像是一个『黑洞』的垃圾桶功能!当你输入的任何东西导向到这个虚拟的垃圾桶装置时,『他就会凭空消失不见了~~』,这个东西有用的很!例如上面的例子中,我们可以这么做,来将错误的信息丢掉!
[test @testtest]# find / -name testing 1> list_right2> /dev/null 很神奇呦! error message 就会『不见了!』呵呵!真高兴!另外,如果我要将数据都写到同一个档案中呢?这个时候写法需要用到特殊写法,请注意底下的写法呦!
[test @testtest]# find / -name testing 1> list 2> list<==错误写法
[test @testtset]# find / -name testing 1> list 2>&1 <==正确写法请特别留意这一点呢!同时写入同一个档案需要使用 2>&1 才对呦!
-
OK!了解了 >, 2>, >> 与 /dev/null 之后,那么那个 < 又是什么呀!?呵呵!以最简单的说法来说,那就是『
将原本需要由键盘输入的数据,
经由档案来读入』的意思,最明显的例子就是mail 这个东西了!我们以 root 的身份来寄信给 root 好了,可以这样做:
1. 完全由键盘输入数据:
[root @testtest]#mail -s "test" root <==-s 表示标题, root 为收件者
I am root!<==以下的数据都是由键盘输入的
That's OK
. <==要结束键盘的输入时,需要在一行的最前面加上. 即可!
CC. <==是否需要有密件副本?不需要的话,直接按下Enter !
EOF <==表示送出的提示字符而已!2. 由档案代替输入
[test @testtset]# mail -s "test" root < /root/.bashrc<==将 .bashrc 内容寄给 root !很有趣吧! ^_^ 这样就可以将信寄出去啰!所以说,熟悉命令重导像的话,对您可是相当的有帮助的呦!
- 好了, 那么为何要使用命令输出重导向呢?这个问题一定会困扰你一下下的,如果你从来都没有写过script 的话!好了,我们来说一说吧!
- 当屏幕输出的信息很重要,而且我们需要将他存下来的时候;
- 背景执行中的程序,不希望他干扰屏幕正常的输出结果时;
- 一些系统的例行命令(例如写在 /etc/crontab 中的档案)的执行结果,希望他可以存下来时;
- 一些执行命令,我们已经知道他可能的错误讯息,所以想以『2> /dev/null 』将他丢掉时;
- 错误讯息与正确讯息需要分别输出时。
- 当然还有很多很多的功能的,最简单的就是网友们常常问到的:『 为何我的root 都会收到系统 crontab 寄来的错误讯息呢』这个咚咚是常见的错误,而如果我们已经知道这个错误讯息是可以忽略的时候,嗯!『2> errorfile 』这个功能就很重要了吧!了解了吗??
管线命令( pipe )
- 就如同前面所说的, bash 命令执行的时候有输出的数据会出现!那么如果这群数据必需要经过几道手续之后才能得到我们所想要的格式,应该如何来设定?这就牵涉到管线命令的问题了(pipe ), 管线命令使用的是『 | 』这个界定符号!另外, 管线命令与『连续下达命令』是不一样的呦!这点底下我们会再说明。底下我们先举一个例子来说明一下简单的管线命令。
- 假设我们要读取 last 这个指令中,那个 root 登入的『次数』应该怎么作?注意呦!我们只需要『 次数』。那么我所进行的步骤是:
- 执行 last ,将所有这个月的所有人登入数据取出来;
- 使用 grep 将上面的输出数据(stdout)当中的 root 撷取出来,其它的不要;
- 使用 wc 这个可以计算行数的指令将上一步的数据计算行数!
-
由于 last 的输出是一行代表一次登入,所以只要计算几行就代表登入几次的意思,所以啰!经由上面三个步骤,将last 数据逐步的筛选,就可以得到我们的数据了!整个命令可以写成如下:
[test @testbin]# last
[test @testbin]# last | grep root
[test @testbin]# last | grep root | wc -l
你可以分别执行『 last 』然后再逐步增加为『 last | grep root 』,最后到上面那一行,那么就马上可以清楚的知道为何会这么做啰!这个管线命令『| 』仅能处理经由前面一个指令传来的正确信息,也就是 standard output ( STDOUT) 的信息,对于 stdandard error 并没有直接处理的能力,请记得。那么整体的管线命令可以使用下图表示之:
-
在每个管线的部分都是『指令』呢!而后一个指令的输入乃是由前一个指令的输出而来的!底下我们来谈一谈一些基本的管线命令指令介绍:
- cut
语法:
说明:[root @test/root ]# cut -d "分隔字符" [-cf] fields
参数说明:
-d :后面接的是用来分隔的字符,预设是『空格符』
-c :后面接的是『第几个字符』
-f :后面接的是第几个区块?
范例:
[root @test/root]# cat /etc/passwd | cut -d ":" -f 1
将 passwd 这个档案里面,每一行里头的: 用来作为分隔号,
而列出第一个区块!也就是姓名所在啦![root @test/root]# last | cut -d " " -f1
以空格符为分隔,并列出第一个区间![root @test/root]# last | cut -c1-20
将 last 之后的数据,每一行的1-20 个字符取出来!
这个 cut 实在很好用!不过,说真的,除非你常常在分析 log 档案,否则使用到cut 的机会并不多!好了! cut 主要的用途在于将『同一行里面的数据进行分解!』,最常使用在分析一些数据或文字数据的时候!这是因为有时候我们会以某些字符当作分割的参数,然后来将数据加以切割,以取得我们所需要的数据。我也很常使用这个功能呢!尤其是在分析log 档案的时候!
- sort
语法:
说明:[root @test/root ]# sort [-t 分隔符] [(+起始)(-结束)][-nru]
参数说明:
-t 分隔符:使用分隔符来隔开不同区间,预设是tab
+start -end:由第start 区间排序到 end 区间
-n :使用『纯数字』排序(否则就会以文字型态来排序)
-r :反向排序
-u :相同出现的一行,只列出一次!
范例:
[root @test/root]# cat /etc/passwd | sort
将列出来的个人账号排序![root @test/root]# cat /etc/passwd | sort -t: +2n
将个人账号中,以使用者ID 来排序(以 : 来分隔,第三个为 ID ,
但第一个代号为0 之故)[root @test/root]# cat /etc/passwd | sort -t: +2nr
反相排序啰!
sort 同样是很常用的指令呢!因为我们常常需要比较一些信息啦!举个上面的第二个例子来说好了!今天假设你有很多的账号,而且你想要知道最大的使用者ID 目前到哪一号了!呵呵!使用 sort 一下子就可以知道答案咯!当然其使用还不止此啦!有空的话不妨玩一玩!
- wc
语法:
说明:[root @test/root ]# wc [-lmw]
参数说明:
-l :多少行
-m :多少字符
-w :多少字?
范例:
[root @test/root]# cat /etc/passwd | wc -l
这个档案里头有多少行?[root @test/root]# cat /etc/passwd | wc -w
这个档案里头有多少字!?
wc 也可以当作指令?呵呵!这可不是上洗手间的 WC 呢!这是相当有用的计算档案内容的一个工具组喔!举个例子来说,当你要知道目前你的账号档案中有多少个账号时,就使用上面的wc -l 啦!因为 /etc/passwd 里头一行代表一个使用者呀!所以知道行数就晓得有多少的账号在里头了!而如果要计算一个档案里头有多少个字符时,呵呵!就使用wc -w 这个参数吧!
- cut
- tee
语法:
说明:[root @test/root ]# last | tee last.list | cut -d " "-f1
参数说明:
范例:
[root @test/root]# last | tee last.list | cut -d " "-f1
有没有发现在命令重导向的时候,如果我们要将数据送出到档案的时候,屏幕上就不会出现任何的数据!那么如果我们需要将数据同时显示在屏幕上跟档案中呢?呵呵!这个时候就需要tee 这个指令啰!使用 last 可以查看到这个月份的登入数据,而使用了tee 之后,会将数据同时传给下一个命令去执行,也会将数据写入 last.list 这个档案中!也是个好帮手!
- tr
语法:
说明:[root @test/root ]# tr [-ds] SET1
参数说明:
-d :删除SET1 这个字符串
-s :取代掉重复的字符!
范例:
[root @test/root]# last | tr '[a-z]' '[A-Z]' <==将小写改成大写
[root @test/root]# cat /etc/passwd | tr -d : <==嘿嘿! : 这个符号在 /etc/passwd 中不见了!
[root @test/root]# cat /home/test/dostxt | tr -d '\r'> dostxt-noM <==将DOS 档案的字尾符号 ^M 的符号去除!
其实这个指令也可以写在『正规表示法』里头!因为他也是由正规表示法的方式来取代数据的!以上面的例子来说,使用[] 可以设定一串字呢!也常常用来取代档案中的怪异符号!例如上面第三个例子当中,可以去除DOS 档案留下来的 ^M 这个断行的符号!这东西相当的有用!相信处理 Linux &Windows 系统中的人们最麻烦的一件事就是这个事情啦!亦即是 DOS 底下会自动的在每行行尾加入^M 这个断行符号!这个时候我们可以使用这个 tr 来将 ^M 去除! ^M 可以使用\r 来代替之!
- split
语法:
说明:[root @test/root ]# split [-bl] 输入档案 输出档案前导字符
参数说明:
-b :以档案size 来分
-l :以行数来分
范例:
[root @test/root]# split -l 5 /etc/passwd test <==会产生 testaa, testab, testac... 等等的档案
在 Windows 的情况下,你要将档案分割需要如何作?!伤脑筋吧!呵呵!在Linux 底下就简单的多了!你要将档案分割的话,那么就使用 -b size 来将一个分割的档案限制其大小,如果是行数的话,那么就使用-l line 来分割!好用的很!如此一来,你就可以轻易的将你的档案分割成 floppy的大小,方便你 copy 啰!
- 管线命令在 bash 的连续的处理程序中是相当重要的!另外,在 log file 的分析当中也是相当重要的一环,所以请特别留意!好嘛!?