Linux学习笔记(十二)
2012-07-16 16:52
197 查看
环境设置文件
要注意的是,我们前几个小节谈到的命令别名啦、自定义的变量啦,在你注销 bash 后就会失效,所以你想要保留你的设定,就得要将这些设定写入配置文件才行。在开始介绍 bash 的配置文件前,我们一定要先知道的就是 login shell 与non-login shell! 重点在于有没有登入 (login) 啦!
login shell:取得 bash 时需要完整的登入流程的,就称为 login shell。举例来说,你要由 tty1 ~ tty6 登入,需要输入用户的账号与密码,此时取得得 bash 就称为『 login shell 』
non-login shell:取得 bash 接口的方法不需要重复登入的举动,举例来说,(1)你以X window 登入 Linux 后, 再以 X 的图形化接口启动终端机,此时那个终端接口并没有需要再次的输入账号与密码,那个 bash 的环境就称为 non-login shell 了。(2)你在原本的bash 环境下再次下达 bash 这个指令,同样的也没有输入账号密码, 那第二个 bash (子程序) 也是 non-login shell 。
为什么要介绍 login, non-login shell 呢?这是因为这两个取得 bash 的情况中,读取的配置文件数据并不一样所致。 由于我们需要登入系统,所以先谈谈 login shell 会读取哪些配置文件?一般来说,login shell 其实只会读取这两个配置文件:
1. /etc/profile:这是系统整体的设定,你最好不要修改这个档案;
2. ~/.bash_profile 或 ~/.bash_login 或 ~/.profile:属于使用者个人设定,你要改自己的数据,就写入这里!
/etc/profile (login shell 才会读) 没事还是不要随便改这个档案喔 这个档案设定的变量主要有:
· PATH:会依据 UID 决定 PATH 变量要不要含有 sbin 的系统指令目录;
· MAIL:依据账号设定好使用者的 mailbox 到/var/spool/mail/账号名;
· USER:根据用户的账号设定此一变量内容;
· HOSTNAME:依据主机的hostname 指令决定此一变量内容;
· HISTSIZE:历史命令记录笔数。CentOS 5.x 设定为 1000 ;
/etc/profile 可不止会做这些事而已,他还会去呼叫外部的设定数据喔!在 CentOS 5.x 默认的情况下,底下这些数据会依序的被呼叫进来:
· /etc/inputrc 其实这个档案并没有被执行啦!/etc/profile 会主动的判断使用者有没有自定义输入的按键功能,如果没有的话,/etc/profile 就会决定设定『INPUTRC=/etc/inputrc』这个变量!此一档案内容为 bash 的热键啦、[tab]要不要有声音啦等等的数据!因为鸟哥觉得 bash 预设的环境已经很棒了,所以不建议修改这个档案!
· /etc/profile.d/*.sh 其实这是个目录内的众多档案!只要在 /etc/profile.d/ 这个目录内且扩展名为 .sh ,另外,使用者能够具有 r 的权限, 那么该档案就会被 /etc/profile 呼叫进来。在 CentOS 5.x 中,这个目录底下的档案规范了 bash 操作接口的颜色、语系、ll 与 ls 指令的命令别名、vi 的命令别名、which 的命令别名等等。如果你需要帮所有使用者设定一些共享的命令别名时, 可以在这个目录底下自行建立扩展名为 .sh 的档案,并将所需要的数据写入即可喔!
· /etc/sysconfig/i18n 这个档案是由 /etc/profile.d/lang.sh 呼叫进来的!这也是我们决定 bash 预设使用何种语系的重要配置文件! 档案里最重要的就是 LANG 这个变量的设定啦!我们在前面的 locale 认识过这个档案啰! 自行回去瞧瞧先!
接下来,让我们来瞧瞧,那么个人偏好的配置文件又是怎么回事?
· ~/.bash_profile (login shell 才会读)
bash 在读完了整体环境设定的 /etc/profile 并由此呼叫其他配置文件后,接下来则是会读取使用者的个人配置文件。 在 login shell的 bash 环境中,所读取的个人偏好配置文件其实主要有三个,依序分别是:
1. ~/.bash_profile
2. ~/.bash_login
3. ~/.profile
其实 bash 的 login shell 设定只会读取上面三个档案的其中一个, 而读取的顺序则是依照上面的顺序。也就是说,如果 ~/.bash_profile 存在,那么其他两个档案不论有无存在,都不会被读取。 如果 ~/.bash_profile 不存在才会去读取 ~/.bash_login,而前两者都不存在才会读取~/.profile 的意思。 会有这么多的档案,其实是因应其他 shell 转换过来的使用者的习惯而已。 先让我们来看一下 root 的 /root/.bash_profile 的内容是怎样呢?
~/.bash_profile:里面定义了个人化的路径(PATH)与环境变量的文件名称!你可以在这里修改你的个人路径呦!当然啰!也可以在 ~/.bashrc 这个个人设定的变量里头修改!有的时候会有 ~/.profile 或 ~/.bash_login 等档案来取代这个档案!
~/.bashrc(non-login shell 会读):这个档案对于个人喜好的 bash 设定来说,是最重要的啦!因为个人都是在这里设定每个人的个性化变量!例如命令别名的设定!路径的重新定义等等,都是在这里完成的!每次执行Shell脚 本的时候都会读取一下这个文件而~/.bash_profile只是在登录时候才读取一次。
~/.bash_history:这个档案的 用途在于将你曾经使用过的命令记录下来,而当你再次的以上下键搜寻或者直接以 history 搜寻的时候,就可以找到曾经使用过的指令啰!需要注意的是 在这一次的执行过程中的指令,将在你离开 shell 之后才会被纪录到这个档案中,否则将只会先被写到暂存内存中(Cache); 可以藉由 history 这个指令来将里头的纪录搜寻出来; 这个档案的指令记录笔数,与 HISTFILE 有关,你可以自行在 ~/.bashrc 里头设定,或者直接由 root 在 /etc/profile 里面统一设定大小!
~/.bash_logout:这个档案则是在『你 注销 shell 的时候, BASH 会为你所做的事情!』通常预设是只有 clear 清除屏幕这件事情而已,不过,你也可以将一些备份或者是其它你认为重要的工作写在这个档案中(例如清空暂存盘),那么当你离开 Linux 的时候,就可以解决一些烦人的事情啰!
最后,我们来看看整个login shell的读取流程:
![](http://my.csdn.net/uploads/201207/16/1342427428_5660.png)
终端的环境设置:stty、set
stty –a 可以将所有的终端设置参数都列出来。
直接利用stty [选项] [所要设置的值]可对“所要的选项”进行设置。几个重要的代表意义是:
· eof : End of file 的意思,代表『结束输入』。
· erase : 向后去除字符,
· intr : 送出一个 interrupt (中断) 的讯号给目前正在 run 的程序;
· kill : 去除在目前指令列上的所有文字;
· quit : 送出一个 quit 的讯号给目前正在 run 的程序;
· start : 在某个程序停止后,重新启动他的 output
· stop : 停止目前屏幕的输出;
· susp : 送出一个 terminal stop 的讯号给正在 run 的程序。
如果你想要用 [ctrl]+h 来进行字符的去除,那么可以下达: [root@www ~]# stty erase ^h 那么从此以后,你的去除字符就得要使用 [ctrl]+h 啰,
bash 环境中的特殊符号有哪些呢?底下我们先汇整一下:
![](http://my.csdn.net/uploads/201207/16/1342427520_9519.png)
![](http://my.csdn.net/uploads/201207/16/1342427538_4846.png)
数据流重导向
![](http://my.csdn.net/uploads/201207/16/1342427571_1693.png)
standard output 与 standard error output
简单的说,标准输出指的是『指令执行所回传的正确的讯息』,而标准错误输出可理解为『 指令执行失败后,所回传的错误讯息』。举个简单例子来说,我们的系统默认有 /etc/crontab 但却无 /etc/vbirdsay, 此时若下达『 cat /etc/crontab /etc/vbirdsay 』这个指令时,cat 会进行:
· 标准输出:读取/etc/crontab 后,将该档案内容显示到屏幕上;
· 标准错误输出:因为无法找到 /etc/vbirdsay,因此在屏幕上显示错误讯息
数据流重导向可以将 standard output (简称 stdout) 与standard error output (简称 stderr) 分别传送到其他的档案或装置去,而分别传送所用的特殊字符则如下所示:
1. 标准输入 (stdin) :代码为 0 ,使用 < 或 << ;
2. 标准输出 (stdout):代码为 1 ,使用 > 或 >> ;
3. 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ;
为了理解 stdout 与stderr ,我们先来进行一个范例的练习:
范例一:观察你的系统根目录 (/) 下各目录的文件名、权限与属性,并记录下来
[root@www ~]# ll / <==此时屏幕会显示出文件名信息
[root@www ~]# ll / > ~/rootfile <==屏幕并无任何信息
[root@www ~]# ll ~/rootfile <==有个新档被建立了!
-rw-r--r-- 1 root root 1089 Feb 6 17:00 /root/rootfile
怪了!屏幕怎么会完全没有数据呢?这是因为原本『 ll / 』所显示的数据已经被重新导向到 ~/rootfile 档案中去了
该档案的建立方式是:
1. 该档案 (本例中是 ~/rootfile) 若不存在,系统会自动的将他建立起来,但是
2. 当这个档案存在的时候,那么系统就会先将这个档案内容清空,然后再将数据写入!
3. 也就是若以 > 输出到一个已存在的档案中,那个档案就会被覆盖掉啰!
改成『 ll / >> ~/rootfile 』 如此一来,当 (1) ~/rootfile 不存在时系统会主动建立这个档案;(2)若该档案已存在, 则数据会在该档案的最下方累加进去!
stderr同上
stdout 与 stderr 分存到不同的档案去
[dmtsai@www ~]$ find /home -name .bashrc > list_right 2> list_error
standard input : < 与 <<
了解了 stderr 与 stdout 后,那么那个 < 又是什么呀?呵呵!以最简单的说法来说, 那就是『将原本需要由键盘输入的数据,改由档案内容来取代』的意思。 我们先由底下的 cat 指令操作来了解一下什么叫做『键盘输入』吧!
范例六:调用 cat 指令来建立一个档案的简单流程
[root@www ~]# cat > catfile
testing
cat file test
<==这里按下 [ctrl]+d 离开
[root@www ~]# cat catfile
testing
cat file test
那我能不能用纯文本文件取代键盘的输入,也就是说,用某个档案的内容来取代键盘的敲击呢? 可以!如下所示:
范例七:用 stdin 取代键盘的输入以建立新档案的简单流程
[root@www ~]# cat > catfile < ~/.bashrc
[root@www ~]# ll catfile ~/.bashrc
-rw-r--r-- 1 root root 194 Sep 26 13:36 /root/.bashrc
-rw-r--r-- 1 root root 194 Feb 6 18:29 catfile
# 注意看,这两个档案的大小会一模一样!几乎像是使用 cp 来复制一般!
命令执行的判断依据: ; , &&, ||
cmd ; cmd (不考虑指令相关性的连续指令下达)
$? (指令回传值) 与 && 或 ||
管线命令 (pipe)
假设我们想要知道 /etc/ 底下有多少档案,那么可以调用 ls /etc 来查阅,不过, 因为 /etc 底下的档案太多,导致一口气就将屏幕塞满了~不知道前面输出的内容是啥?此时,我们可以透过 less 指令的协助,调用: [root@www ~]# ls -al /etc | less
![](http://my.csdn.net/uploads/201207/16/1342428360_8402.png)
管线命令主要有两个比较需要注意的地方:
· 管线命令仅会处理 standard output,对于 standard error output 会予以忽略
· 管线命令必须要能够接受来自前一个指令的数据成为 standard input 继续处理才行。
撷取命令: cut, grep
一般来说,撷取讯息通常是针对『一行一行』来分析的,并不是整篇讯息分析的喔
cut
[root@www ~]# cut -d'分隔字符' -f fields <==用于有特定分隔字符
[root@www ~]# cut -c 字符区间 <==用于排列整齐的讯息
选项与参数:
-d :后面接分隔字符。与 -f 一起使用;
-f :依据 -d 的分隔字符将一段讯息分割成为数段,用 -f 取出第几段的意思;
-c :以字符 (characters) 的单位取出固定字符区间;
范例一:将 PATH 变量取出,我要找出第五个路径。
[root@www ~]# echo $PATH
/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin:/usr/games:
# 1 | 2 | 3 | 4 | 5 | 6 | 7
[root@www ~]# echo $PATH | cut -d ':' -f 5
# 如同上面的数字显示,我们是以『 : 』作为分隔,因此会出现 /usr/local/bin
# 那么如果想要列出第 3 与第 5 呢?,就是这样:
[root@www ~]# echo $PATH | cut -d ':' -f 3,5
grep
刚刚的 cut 是将一行讯息当中,取出某部分我们想要得,而 grep 则是分析一行讯息, 若当中有我们所需要的信息,就将该行拿出来~简单的语法是这样的:
[root@www ~]# grep [-acinv] [--color=auto] '搜寻字符串' filename
选项与参数:
-a :将 binary 档案以 text 档案的方式搜寻数据
-c :计算找到 '搜寻字符串' 的次数
-i :忽略大小写的不同,所以大小写规为相同
-n :顺便输出行号
-v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!
--color=auto :可以将找到的关键词部分加上颜色的显示喔!
范例一:将 last 当中,有出现 root 的那一行就取出来;
[root@www ~]# last | grep 'root'
范例二:与范例一相反,只要没有 root 的就取出!
[root@www ~]# last | grep -v 'root'
范例三:在 last 的输出讯息中,只要有 root 就取出,并且仅取第一栏
[root@www ~]# last | grep 'root' |cut -d ' ' -f1
# 在取出 root 之后,调用上个指令 cut 处理,就能够仅取得第一栏啰!
排序命令: sort, wc, uniq
Sort
如果您需要排序时,建议使用LANG=C 来让语系统一,数据排序比较好一些。
[root@www ~]# sort [-fbMnrtuk] [file or stdin]
选项与参数:
-f :忽略大小写的差异,例如 A 与 a 规为编码相同;
-b :忽略最前面的空格符部分;
-M :以月份的名字来排序,例如 JAN, DEC 等等的排序方法;
-n :使用『纯数字』进行排序(默认是以文字型态来排序的);
-r :反向排序;
-u :就是 uniq ,相同的数据中,仅出现一行代表;
-t :分隔符,预设是用 [tab] 键来分隔;
-k :以那个区间 (field) 来进行排序的意思
范例一:个人账号都记录在 /etc/passwd 下,请将账号进行排序。
[root@www ~]# cat /etc/passwd | sort
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
# 鸟哥省略很多的输出~由上面的数据看起来, sort 是预设『以第一个』数据来排序,
# 而且默认是以『文字』型态来排序的喔!所以由 a 开始排到最后啰!
uniq
如果我排序完成了,想要将重复的资料仅列出一个显示,可以怎么做呢?
[root@www ~]# uniq [-ic]
选项与参数:
-i :忽略大小写字符的不同;
-c :进行计数
范例一:使用 last 将账号列出,仅取出账号栏,进行排序后仅取出一位;
[root@www ~]# last | cut -d ' ' -f1 | sort | uniq
范例二:承上题,如果我还想要知道每个人的登入总次数呢?
[root@www ~]# last | cut -d ' ' -f1 | sort | uniq -c
1
12 reboot
41 root
1 wtmp
# 仍上面的结果可以发现 reboot 有 12 次, root 登入则有 41 次!
# wtmp 与第一行的空白都是 last 的默认字符,那两个可以忽略的!
wc
如果我想要知道 /etc/man.config 这个档案里面有多少字?多少行?多少字符的话, 可以怎么做呢?其实可以调用 wc 这个指令来达成喔!他可以帮我们计算输出的讯息的整体数据!
[root@www ~]# wc [-lwm]
选项与参数:
-l :仅列出行;
-w :仅列出多少字(英文单字);
-m :多少字符;
范例一:那个 /etc/man.config 里面到底有多少相关字、行、字符数?
[root@www ~]# cat /etc/man.config | wc
141 722 4617
# 输出的三个数字中,分别代表: 『行、字数、字符数』
范例二:我知道使用 last 可以输出登入者,但是 last 最后两行并非账号内容, 那么请问,我该如何以一行指令串取得这个月份登入系统的总人次?
[root@www ~]# last | grep [a-zA-Z] | grep -v 'wtmp' | wc -l
# 由亍 last 会输出空白行与 wtmp 字样在最底下两行,因此,我调用
# grep 取出非空白行,以及去除 wtmp 那一行,在计算行数,就能够了解啰!
双向重导向: tee
想个简单的东西,我们由前一节知道 > 会将数据流整个传送给档案或装置,因此我们除非去读取该档案或装置, 否则就无法继续调用这个数据流。万一我想要将这个数据流的处理过程中将某段讯息存下来,应该怎么做? 调用 tee 就可以啰~我们可以这样简单看一下:
![](http://my.csdn.net/uploads/201207/16/1342428758_8611.png)
tee 会同时将数据流分送到档案去与屏幕 (screen);而输出到屏幕的,其实就是 stdout ,可以让下个指令继续处理喔!
[root@www ~]# tee [-a] file
选项与参数:
-a :以累加 (append) 的方式,将数据加入 file 当中!
[root@www ~]# last | tee last.list | cut -d " " -f1
# 这个范例可以让我们将 last 的输出存一份到 last.list 档案中;
[root@www ~]# ls -l /home | tee ~/homefile | more
# 这个范例则是将 ls 的数据存一份到 ~/homefile ,同时屏幕也有输出讯息!
[root@www ~]# ls -l / | tee -a ~/homefile | more
# 要注意! tee 后接的档案会被覆盖,若加上 -a 这个选项则能将讯息累加。
字符转换命令: tr, col, join, paste, expand
tr 可以用来去除一段讯息当中的文字,或者是进行文字讯息的替换!
[root@www ~]# tr [-ds] SET1 ...
选项与参数:
-d :去除讯息当中的 SET1 这个字符串;
-s :取代掉重复的字符!
范例一:将 last 输出的讯息中,所有的小写变成大写字符:
[root@www ~]# last | tr '[a-z]' '[A-Z]'
# 事实上,没有加上单引号也是可以执行的,如:『 last | tr [a-z] [A-Z] 』
范例二:将 /etc/passwd 输出的讯息中,将冒号 (:) 去除
[root@www ~]# cat /etc/passwd | tr -d ':'
范例三:将 /etc/passwd 转存成 dos 断行到 /root/passwd 中,再将 ^M 符号去除
[root@www ~]# cp /etc/passwd /root/passwd && unix2dos /root/passwd
[root@www ~]# file /etc/passwd /root/passwd
/etc/passwd: ASCII text
/root/passwd: ASCII text, with CRLF line terminators <==就是 DOS 断行
[root@www ~]# cat /root/passwd | tr -d '\r' > /root/passwd.linux
# 那个 \r 指的是 DOS 哦断行字符,关于更多的字符,请参考 man tr
[root@www ~]# ll /etc/passwd /root/passwd*
-rw-r--r-- 1 root root 1986 Feb 6 17:55 /etc/passwd
-rw-r--r-- 1 root root 2030 Feb 7 15:55 /root/passwd
-rw-r--r-- 1 root root 1986 Feb 7 15:57 /root/passwd.linux
# 处理过后,发现档案大小与原本的 /etc/passwd 就一致了!
col
[root@www ~]# col [-xb]
选项与参数:
-x :将 tab 键转换成对等的空格键
-b :在文字内有反斜杠 (/) 时,仅保留反斜杠最后接的那个字符
范例一:调用 cat -A 显示出所有特殊按键,最后以 col 将 [tab] 转成空白
[root@www ~]# cat -A /etc/man.config <==此时会看到很多 ^I 的符号,那就是 tab
[root@www ~]# cat /etc/man.config | col -x | cat -A | more
# 嘿嘿!如此一来, [tab] 按键会被取代成为空格键,输出就美观多了!
范例二:将 col 的 man page 转存成为 /root/col.man 得纯文本档
[root@www ~]# man col > /root/col.man
[root@www ~]# vi /root/col.man
COL(1) BSD General Commands Manual COL(1)
N^HNA^HAM^HME^HE
c^Hco^Hol^Hl - filter reverse line feeds from input
S^HSY^HYN^HNO^HOP^HPS^HSI^HIS^HS
c^Hco^Hol^Hl [-^H-b^Hbf^Hfp^Hpx^Hx] [-^H-l^Hl
_^Hn_^Hu_^Hm]
# 你没看错!由于 man page 内有些特殊按钮会用来作为类似特殊按键与颜色显示,
# 所以这个档案内就会出现如上所示的一堆怪异字符(有 ^ 的)
[root@www ~]# man col | col -b > /root/col.man
join
join 看字面上的意义 (加入/参加) 就可以知道,他是在处理两个档案之间的数据, 而且,主要是在处理『两个档案当中,有 "相同数据" 的那一行,才将他加在一起』的意思。我们调用底下的简单例子来说明:
[root@www ~]# join [-ti12] file1 file2
选项与参数:
-t :join 默认以空格符分隔数据,并且比对『第一个字段』的数据,如果两个档案相同,则将两笔数据联成一行,且第一个字段放在第一个!
-i :忽略大小写的差异;
-1 :这个是数字的 1 ,代表『第一个档案要用那个字段来分析』的意思;
-2 :代表『第二个档案要用那个字段来分析』的意思。
范例一:用 root 的身份,将 /etc/passwd 与 /etc/shadow 相关数据整合成一栏
[root@www ~]# head -n 3 /etc/passwd /etc/shadow
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
==> /etc/shadow <==
root:$1$/3AQpE5e$y9A/D0bh6rElAs:14120:0:99999:7:::
bin:*:14126:0:99999:7:::
daemon:*:14126:0:99999:7:::
# 由输出的资料可以发现这两个档案的最左边字段都是账号!且以 : 分隔
[root@www ~]# join -t ':' /etc/passwd /etc/shadow
root:x:0:0:root:/root:/bin/bash:$1$/3AQpE5e$y9A/D0bh6rElAs:14120:0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin:*:14126:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:14126:0:99999:7:::
# 透过上面这个动作,我们可以将两个档案第一字段相同者整合成一行!
# 第二个档案的相同字段并不会显示(因为已经在第一行了嘛!)
paste
这个 paste 就要比 join 简单多了!相对于 join 必须要比对两个档案的数据相关性, paste 就直接『将两行贴在一起,且中间以 [tab] 键隔开』而已!简单的使用方法:
[root@www ~]# paste [-d] file1 file2
选项与参数:
-d :后面可以接分隔字符。预设是以 [tab] 来分隔的!
- :如果 file 部分写成 - ,表示来自 standard input 的资料的意思。
范例一:将 /etc/passwd 与 /etc/shadow 同一行贴在一起
[root@www ~]# paste /etc/passwd /etc/shadow
bin:x:1:1:bin:/bin:/sbin/nologin bin:*:14126:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:14126:0:99999:7:::
adm:x:3:4:adm:/var/adm:/sbin/nologin adm:*:14126:0:99999:7:::
# 注意喔!同一行中间是以 [tab] 按键隔开的!
范例二:先将 /etc/group 读出(用 cat),然后与范例一贴上一起!且仅取出前三行
[root@www ~]# cat /etc/group|paste /etc/passwd /etc/shadow -|head -n
3
# 这个例子得重点在那个 - 的使用!那玩意儿常常代表 stdin 喔!
expand
这玩意儿就是在将 [tab] 按键转成空格键啦~可以这样玩:
[root@www ~]# expand [-t] file
选项与参数:
-t :后面可以接数字。一般来说,一个 tab 按键可以用 8 个空格键取代。我们也可以自行定义一个 [tab] 按键代表多少个字符呢!
范例一:将 /etc/man.config 内行首为 MANPATH 癿字样就取出;仅取前三行;
[root@www ~]# grep '^MANPATH' /etc/man.config | head -n 3
MANPATH /usr/man
MANPATH /usr/share/man
MANPATH /usr/local/man
# 行首得代表标志为 ^ ,这个我们留待下节介绍!先有概念即可!
范例二:承上,如果我想要将所有的符号都列出来?(用 cat)
[root@www ~]# grep '^MANPATH' /etc/man.config | head -n 3 |cat -A
MANPATH^I/usr/man$
MANPATH^I/usr/share/man$
MANPATH^I/usr/local/man$
# 发现差别了吗?没错~ [tab] 按键可以被 cat -A 显示成为 ^I
分割命令: split
如果你有档案太大,导致一些携带式装置无法复制的问题,嘿嘿!找 split 就对了! 他可以帮你将一个大档案,依据档案大小或行数来分割,就可以将大档案分割成为小档案了! 快速又有效啊!真不错~
[root@www ~]# split [-bl] file PREFIX
选项与参数:
-b :后面可接欲分割成的档案大小,可加单位,例如 b, k, m 等;
-l :以行数来进行分割。
PREFIX :代表前导符的意思,可作为分割档案的前导文字。
范例一:我的 /etc/termcap 有七百多K,若想要分成 300K 一个档案时?
[root@www ~]# cd /tmp; split -b 300k /etc/termcap termcap
[root@www tmp]# ll -k termcap*
-rw-r--r-- 1 root root 300 Feb 7 16:39 termcapaa
-rw-r--r-- 1 root root 300 Feb 7 16:39 termcapab
-rw-r--r-- 1 root root 189 Feb 7 16:39 termcapac
# 那个档名可以随意取的啦!我们只要写上前导文字,小档案就会以
# xxxaa, xxxab, xxxac 等方式来建立小档案的!
范例二:如何将上面的三个小档案合成一个档案,档名为 termcapback
[root@www tmp]# cat termcap* >> termcapback
# 很简单吧?就用数据流重导向就好啦!简单!
参数代换: xargs
xargs 可以读入 stdin 的数据,并且以空格符或断行字符作为分辨,将 stdin 的资料分隔成为 arguments 。
[root@www ~]# xargs [-0epn] command
选项与参数:
-0 :如果输入的stdin 含有特殊字符,例如 `, \, 空格键等等字符时,这个 -0 参数 可以将他还原成一般字符。这个参数可以用于特殊状态喔!
-e :这个是 EOF (end of file) 的意思。后面可以接一个字符串,当 xargs 分析到这个字符串时,就会停止继续工作!
-p :在执行每个指令的 argument 时,都会询问使用者的意思;
-n :后面接次数,每次 command 指令执行时,要使用几个参数的意思。看范例三。
当 xargs 后面没有接任何的指令时,默认是以 echo 来进行输出喔!
范例一:将 /etc/passwd 内的第一栏取出,仅取三行,使用 finger 这个指令将每个账号内容秀出来
[root@www ~]# cut -d':' -f1 /etc/passwd |head -n 3| xargs finger
Login: root Name: root
Directory: /root Shell: /bin/bash
Never logged in.
No mail.
No Plan.
......底下省略.....
# 由 finger account 可以取得该账号的相关说明内容,例如上面的输出就是
finger root
# 后的结果。在这个例子当中,我们调用 cut取出账号名称,用 head 取出三个
账号,
# 最后则是由 xargs 将三个账号的名称发成 finger 后面需要的参数!
范例二:同上,但是每次执行 finger 时,都要询问使用者是否动作?
[root@www ~]# cut -d':' -f1 /etc/passwd |head -n 3| xargs -p finger
finger root bin daemon ?...y
.....(底下省略)....
# 呵呵!这个 -p 的选项可以让用户的使用过程中,被询问到每个指令是否执行!
关于减号 - 的用途
管线命令在 bash 的连续的处理程序中是相当重要的!另外,在 log file 的分析当中也是相当重要的一环, 所以请特别留意!另外,在管线命令当中,常常会使用到前一个指令的 stdout 作为这次的 stdin , 某些指令需要用到文件名 (例如 tar) 来进行处理时,该 stdin 与stdout 可以调用减号 "-" 来替代,举例来说:
root@www ~]# tar -cvf - /home | tar -xvf -
上面这个例子是说:『我将 /home 里面的档案给他打包,但打包的数据不是记录到档案,而是传送到 stdout; 经过管线后,将 tar -cvf - /home 传送给后面的 tar -xvf - 』。后面的这个 - 则是取用前一个指令的 stdout, 因此,我们就不需要使用 file 了!这是很常见的例子喔!注意注意!
要注意的是,我们前几个小节谈到的命令别名啦、自定义的变量啦,在你注销 bash 后就会失效,所以你想要保留你的设定,就得要将这些设定写入配置文件才行。在开始介绍 bash 的配置文件前,我们一定要先知道的就是 login shell 与non-login shell! 重点在于有没有登入 (login) 啦!
login shell:取得 bash 时需要完整的登入流程的,就称为 login shell。举例来说,你要由 tty1 ~ tty6 登入,需要输入用户的账号与密码,此时取得得 bash 就称为『 login shell 』
non-login shell:取得 bash 接口的方法不需要重复登入的举动,举例来说,(1)你以X window 登入 Linux 后, 再以 X 的图形化接口启动终端机,此时那个终端接口并没有需要再次的输入账号与密码,那个 bash 的环境就称为 non-login shell 了。(2)你在原本的bash 环境下再次下达 bash 这个指令,同样的也没有输入账号密码, 那第二个 bash (子程序) 也是 non-login shell 。
为什么要介绍 login, non-login shell 呢?这是因为这两个取得 bash 的情况中,读取的配置文件数据并不一样所致。 由于我们需要登入系统,所以先谈谈 login shell 会读取哪些配置文件?一般来说,login shell 其实只会读取这两个配置文件:
1. /etc/profile:这是系统整体的设定,你最好不要修改这个档案;
2. ~/.bash_profile 或 ~/.bash_login 或 ~/.profile:属于使用者个人设定,你要改自己的数据,就写入这里!
/etc/profile (login shell 才会读) 没事还是不要随便改这个档案喔 这个档案设定的变量主要有:
· PATH:会依据 UID 决定 PATH 变量要不要含有 sbin 的系统指令目录;
· MAIL:依据账号设定好使用者的 mailbox 到/var/spool/mail/账号名;
· USER:根据用户的账号设定此一变量内容;
· HOSTNAME:依据主机的hostname 指令决定此一变量内容;
· HISTSIZE:历史命令记录笔数。CentOS 5.x 设定为 1000 ;
/etc/profile 可不止会做这些事而已,他还会去呼叫外部的设定数据喔!在 CentOS 5.x 默认的情况下,底下这些数据会依序的被呼叫进来:
· /etc/inputrc 其实这个档案并没有被执行啦!/etc/profile 会主动的判断使用者有没有自定义输入的按键功能,如果没有的话,/etc/profile 就会决定设定『INPUTRC=/etc/inputrc』这个变量!此一档案内容为 bash 的热键啦、[tab]要不要有声音啦等等的数据!因为鸟哥觉得 bash 预设的环境已经很棒了,所以不建议修改这个档案!
· /etc/profile.d/*.sh 其实这是个目录内的众多档案!只要在 /etc/profile.d/ 这个目录内且扩展名为 .sh ,另外,使用者能够具有 r 的权限, 那么该档案就会被 /etc/profile 呼叫进来。在 CentOS 5.x 中,这个目录底下的档案规范了 bash 操作接口的颜色、语系、ll 与 ls 指令的命令别名、vi 的命令别名、which 的命令别名等等。如果你需要帮所有使用者设定一些共享的命令别名时, 可以在这个目录底下自行建立扩展名为 .sh 的档案,并将所需要的数据写入即可喔!
· /etc/sysconfig/i18n 这个档案是由 /etc/profile.d/lang.sh 呼叫进来的!这也是我们决定 bash 预设使用何种语系的重要配置文件! 档案里最重要的就是 LANG 这个变量的设定啦!我们在前面的 locale 认识过这个档案啰! 自行回去瞧瞧先!
接下来,让我们来瞧瞧,那么个人偏好的配置文件又是怎么回事?
· ~/.bash_profile (login shell 才会读)
bash 在读完了整体环境设定的 /etc/profile 并由此呼叫其他配置文件后,接下来则是会读取使用者的个人配置文件。 在 login shell的 bash 环境中,所读取的个人偏好配置文件其实主要有三个,依序分别是:
1. ~/.bash_profile
2. ~/.bash_login
3. ~/.profile
其实 bash 的 login shell 设定只会读取上面三个档案的其中一个, 而读取的顺序则是依照上面的顺序。也就是说,如果 ~/.bash_profile 存在,那么其他两个档案不论有无存在,都不会被读取。 如果 ~/.bash_profile 不存在才会去读取 ~/.bash_login,而前两者都不存在才会读取~/.profile 的意思。 会有这么多的档案,其实是因应其他 shell 转换过来的使用者的习惯而已。 先让我们来看一下 root 的 /root/.bash_profile 的内容是怎样呢?
~/.bash_profile:里面定义了个人化的路径(PATH)与环境变量的文件名称!你可以在这里修改你的个人路径呦!当然啰!也可以在 ~/.bashrc 这个个人设定的变量里头修改!有的时候会有 ~/.profile 或 ~/.bash_login 等档案来取代这个档案!
~/.bashrc(non-login shell 会读):这个档案对于个人喜好的 bash 设定来说,是最重要的啦!因为个人都是在这里设定每个人的个性化变量!例如命令别名的设定!路径的重新定义等等,都是在这里完成的!每次执行Shell脚 本的时候都会读取一下这个文件而~/.bash_profile只是在登录时候才读取一次。
~/.bash_history:这个档案的 用途在于将你曾经使用过的命令记录下来,而当你再次的以上下键搜寻或者直接以 history 搜寻的时候,就可以找到曾经使用过的指令啰!需要注意的是 在这一次的执行过程中的指令,将在你离开 shell 之后才会被纪录到这个档案中,否则将只会先被写到暂存内存中(Cache); 可以藉由 history 这个指令来将里头的纪录搜寻出来; 这个档案的指令记录笔数,与 HISTFILE 有关,你可以自行在 ~/.bashrc 里头设定,或者直接由 root 在 /etc/profile 里面统一设定大小!
~/.bash_logout:这个档案则是在『你 注销 shell 的时候, BASH 会为你所做的事情!』通常预设是只有 clear 清除屏幕这件事情而已,不过,你也可以将一些备份或者是其它你认为重要的工作写在这个档案中(例如清空暂存盘),那么当你离开 Linux 的时候,就可以解决一些烦人的事情啰!
最后,我们来看看整个login shell的读取流程:
![](http://my.csdn.net/uploads/201207/16/1342427428_5660.png)
终端的环境设置:stty、set
stty –a 可以将所有的终端设置参数都列出来。
直接利用stty [选项] [所要设置的值]可对“所要的选项”进行设置。几个重要的代表意义是:
· eof : End of file 的意思,代表『结束输入』。
· erase : 向后去除字符,
· intr : 送出一个 interrupt (中断) 的讯号给目前正在 run 的程序;
· kill : 去除在目前指令列上的所有文字;
· quit : 送出一个 quit 的讯号给目前正在 run 的程序;
· start : 在某个程序停止后,重新启动他的 output
· stop : 停止目前屏幕的输出;
· susp : 送出一个 terminal stop 的讯号给正在 run 的程序。
如果你想要用 [ctrl]+h 来进行字符的去除,那么可以下达: [root@www ~]# stty erase ^h 那么从此以后,你的去除字符就得要使用 [ctrl]+h 啰,
bash 环境中的特殊符号有哪些呢?底下我们先汇整一下:
![](http://my.csdn.net/uploads/201207/16/1342427520_9519.png)
![](http://my.csdn.net/uploads/201207/16/1342427538_4846.png)
数据流重导向
![](http://my.csdn.net/uploads/201207/16/1342427571_1693.png)
standard output 与 standard error output
简单的说,标准输出指的是『指令执行所回传的正确的讯息』,而标准错误输出可理解为『 指令执行失败后,所回传的错误讯息』。举个简单例子来说,我们的系统默认有 /etc/crontab 但却无 /etc/vbirdsay, 此时若下达『 cat /etc/crontab /etc/vbirdsay 』这个指令时,cat 会进行:
· 标准输出:读取/etc/crontab 后,将该档案内容显示到屏幕上;
· 标准错误输出:因为无法找到 /etc/vbirdsay,因此在屏幕上显示错误讯息
数据流重导向可以将 standard output (简称 stdout) 与standard error output (简称 stderr) 分别传送到其他的档案或装置去,而分别传送所用的特殊字符则如下所示:
1. 标准输入 (stdin) :代码为 0 ,使用 < 或 << ;
2. 标准输出 (stdout):代码为 1 ,使用 > 或 >> ;
3. 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ;
为了理解 stdout 与stderr ,我们先来进行一个范例的练习:
范例一:观察你的系统根目录 (/) 下各目录的文件名、权限与属性,并记录下来
[root@www ~]# ll / <==此时屏幕会显示出文件名信息
[root@www ~]# ll / > ~/rootfile <==屏幕并无任何信息
[root@www ~]# ll ~/rootfile <==有个新档被建立了!
-rw-r--r-- 1 root root 1089 Feb 6 17:00 /root/rootfile
怪了!屏幕怎么会完全没有数据呢?这是因为原本『 ll / 』所显示的数据已经被重新导向到 ~/rootfile 档案中去了
该档案的建立方式是:
1. 该档案 (本例中是 ~/rootfile) 若不存在,系统会自动的将他建立起来,但是
2. 当这个档案存在的时候,那么系统就会先将这个档案内容清空,然后再将数据写入!
3. 也就是若以 > 输出到一个已存在的档案中,那个档案就会被覆盖掉啰!
改成『 ll / >> ~/rootfile 』 如此一来,当 (1) ~/rootfile 不存在时系统会主动建立这个档案;(2)若该档案已存在, 则数据会在该档案的最下方累加进去!
stderr同上
stdout 与 stderr 分存到不同的档案去
[dmtsai@www ~]$ find /home -name .bashrc > list_right 2> list_error
standard input : < 与 <<
了解了 stderr 与 stdout 后,那么那个 < 又是什么呀?呵呵!以最简单的说法来说, 那就是『将原本需要由键盘输入的数据,改由档案内容来取代』的意思。 我们先由底下的 cat 指令操作来了解一下什么叫做『键盘输入』吧!
范例六:调用 cat 指令来建立一个档案的简单流程
[root@www ~]# cat > catfile
testing
cat file test
<==这里按下 [ctrl]+d 离开
[root@www ~]# cat catfile
testing
cat file test
那我能不能用纯文本文件取代键盘的输入,也就是说,用某个档案的内容来取代键盘的敲击呢? 可以!如下所示:
范例七:用 stdin 取代键盘的输入以建立新档案的简单流程
[root@www ~]# cat > catfile < ~/.bashrc
[root@www ~]# ll catfile ~/.bashrc
-rw-r--r-- 1 root root 194 Sep 26 13:36 /root/.bashrc
-rw-r--r-- 1 root root 194 Feb 6 18:29 catfile
# 注意看,这两个档案的大小会一模一样!几乎像是使用 cp 来复制一般!
命令执行的判断依据: ; , &&, ||
cmd ; cmd (不考虑指令相关性的连续指令下达)
$? (指令回传值) 与 && 或 ||
管线命令 (pipe)
假设我们想要知道 /etc/ 底下有多少档案,那么可以调用 ls /etc 来查阅,不过, 因为 /etc 底下的档案太多,导致一口气就将屏幕塞满了~不知道前面输出的内容是啥?此时,我们可以透过 less 指令的协助,调用: [root@www ~]# ls -al /etc | less
![](http://my.csdn.net/uploads/201207/16/1342428360_8402.png)
管线命令主要有两个比较需要注意的地方:
· 管线命令仅会处理 standard output,对于 standard error output 会予以忽略
· 管线命令必须要能够接受来自前一个指令的数据成为 standard input 继续处理才行。
撷取命令: cut, grep
一般来说,撷取讯息通常是针对『一行一行』来分析的,并不是整篇讯息分析的喔
cut
[root@www ~]# cut -d'分隔字符' -f fields <==用于有特定分隔字符
[root@www ~]# cut -c 字符区间 <==用于排列整齐的讯息
选项与参数:
-d :后面接分隔字符。与 -f 一起使用;
-f :依据 -d 的分隔字符将一段讯息分割成为数段,用 -f 取出第几段的意思;
-c :以字符 (characters) 的单位取出固定字符区间;
范例一:将 PATH 变量取出,我要找出第五个路径。
[root@www ~]# echo $PATH
/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin:/usr/games:
# 1 | 2 | 3 | 4 | 5 | 6 | 7
[root@www ~]# echo $PATH | cut -d ':' -f 5
# 如同上面的数字显示,我们是以『 : 』作为分隔,因此会出现 /usr/local/bin
# 那么如果想要列出第 3 与第 5 呢?,就是这样:
[root@www ~]# echo $PATH | cut -d ':' -f 3,5
grep
刚刚的 cut 是将一行讯息当中,取出某部分我们想要得,而 grep 则是分析一行讯息, 若当中有我们所需要的信息,就将该行拿出来~简单的语法是这样的:
[root@www ~]# grep [-acinv] [--color=auto] '搜寻字符串' filename
选项与参数:
-a :将 binary 档案以 text 档案的方式搜寻数据
-c :计算找到 '搜寻字符串' 的次数
-i :忽略大小写的不同,所以大小写规为相同
-n :顺便输出行号
-v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!
--color=auto :可以将找到的关键词部分加上颜色的显示喔!
范例一:将 last 当中,有出现 root 的那一行就取出来;
[root@www ~]# last | grep 'root'
范例二:与范例一相反,只要没有 root 的就取出!
[root@www ~]# last | grep -v 'root'
范例三:在 last 的输出讯息中,只要有 root 就取出,并且仅取第一栏
[root@www ~]# last | grep 'root' |cut -d ' ' -f1
# 在取出 root 之后,调用上个指令 cut 处理,就能够仅取得第一栏啰!
排序命令: sort, wc, uniq
Sort
如果您需要排序时,建议使用LANG=C 来让语系统一,数据排序比较好一些。
[root@www ~]# sort [-fbMnrtuk] [file or stdin]
选项与参数:
-f :忽略大小写的差异,例如 A 与 a 规为编码相同;
-b :忽略最前面的空格符部分;
-M :以月份的名字来排序,例如 JAN, DEC 等等的排序方法;
-n :使用『纯数字』进行排序(默认是以文字型态来排序的);
-r :反向排序;
-u :就是 uniq ,相同的数据中,仅出现一行代表;
-t :分隔符,预设是用 [tab] 键来分隔;
-k :以那个区间 (field) 来进行排序的意思
范例一:个人账号都记录在 /etc/passwd 下,请将账号进行排序。
[root@www ~]# cat /etc/passwd | sort
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
# 鸟哥省略很多的输出~由上面的数据看起来, sort 是预设『以第一个』数据来排序,
# 而且默认是以『文字』型态来排序的喔!所以由 a 开始排到最后啰!
uniq
如果我排序完成了,想要将重复的资料仅列出一个显示,可以怎么做呢?
[root@www ~]# uniq [-ic]
选项与参数:
-i :忽略大小写字符的不同;
-c :进行计数
范例一:使用 last 将账号列出,仅取出账号栏,进行排序后仅取出一位;
[root@www ~]# last | cut -d ' ' -f1 | sort | uniq
范例二:承上题,如果我还想要知道每个人的登入总次数呢?
[root@www ~]# last | cut -d ' ' -f1 | sort | uniq -c
1
12 reboot
41 root
1 wtmp
# 仍上面的结果可以发现 reboot 有 12 次, root 登入则有 41 次!
# wtmp 与第一行的空白都是 last 的默认字符,那两个可以忽略的!
wc
如果我想要知道 /etc/man.config 这个档案里面有多少字?多少行?多少字符的话, 可以怎么做呢?其实可以调用 wc 这个指令来达成喔!他可以帮我们计算输出的讯息的整体数据!
[root@www ~]# wc [-lwm]
选项与参数:
-l :仅列出行;
-w :仅列出多少字(英文单字);
-m :多少字符;
范例一:那个 /etc/man.config 里面到底有多少相关字、行、字符数?
[root@www ~]# cat /etc/man.config | wc
141 722 4617
# 输出的三个数字中,分别代表: 『行、字数、字符数』
范例二:我知道使用 last 可以输出登入者,但是 last 最后两行并非账号内容, 那么请问,我该如何以一行指令串取得这个月份登入系统的总人次?
[root@www ~]# last | grep [a-zA-Z] | grep -v 'wtmp' | wc -l
# 由亍 last 会输出空白行与 wtmp 字样在最底下两行,因此,我调用
# grep 取出非空白行,以及去除 wtmp 那一行,在计算行数,就能够了解啰!
双向重导向: tee
想个简单的东西,我们由前一节知道 > 会将数据流整个传送给档案或装置,因此我们除非去读取该档案或装置, 否则就无法继续调用这个数据流。万一我想要将这个数据流的处理过程中将某段讯息存下来,应该怎么做? 调用 tee 就可以啰~我们可以这样简单看一下:
![](http://my.csdn.net/uploads/201207/16/1342428758_8611.png)
tee 会同时将数据流分送到档案去与屏幕 (screen);而输出到屏幕的,其实就是 stdout ,可以让下个指令继续处理喔!
[root@www ~]# tee [-a] file
选项与参数:
-a :以累加 (append) 的方式,将数据加入 file 当中!
[root@www ~]# last | tee last.list | cut -d " " -f1
# 这个范例可以让我们将 last 的输出存一份到 last.list 档案中;
[root@www ~]# ls -l /home | tee ~/homefile | more
# 这个范例则是将 ls 的数据存一份到 ~/homefile ,同时屏幕也有输出讯息!
[root@www ~]# ls -l / | tee -a ~/homefile | more
# 要注意! tee 后接的档案会被覆盖,若加上 -a 这个选项则能将讯息累加。
字符转换命令: tr, col, join, paste, expand
tr 可以用来去除一段讯息当中的文字,或者是进行文字讯息的替换!
[root@www ~]# tr [-ds] SET1 ...
选项与参数:
-d :去除讯息当中的 SET1 这个字符串;
-s :取代掉重复的字符!
范例一:将 last 输出的讯息中,所有的小写变成大写字符:
[root@www ~]# last | tr '[a-z]' '[A-Z]'
# 事实上,没有加上单引号也是可以执行的,如:『 last | tr [a-z] [A-Z] 』
范例二:将 /etc/passwd 输出的讯息中,将冒号 (:) 去除
[root@www ~]# cat /etc/passwd | tr -d ':'
范例三:将 /etc/passwd 转存成 dos 断行到 /root/passwd 中,再将 ^M 符号去除
[root@www ~]# cp /etc/passwd /root/passwd && unix2dos /root/passwd
[root@www ~]# file /etc/passwd /root/passwd
/etc/passwd: ASCII text
/root/passwd: ASCII text, with CRLF line terminators <==就是 DOS 断行
[root@www ~]# cat /root/passwd | tr -d '\r' > /root/passwd.linux
# 那个 \r 指的是 DOS 哦断行字符,关于更多的字符,请参考 man tr
[root@www ~]# ll /etc/passwd /root/passwd*
-rw-r--r-- 1 root root 1986 Feb 6 17:55 /etc/passwd
-rw-r--r-- 1 root root 2030 Feb 7 15:55 /root/passwd
-rw-r--r-- 1 root root 1986 Feb 7 15:57 /root/passwd.linux
# 处理过后,发现档案大小与原本的 /etc/passwd 就一致了!
col
[root@www ~]# col [-xb]
选项与参数:
-x :将 tab 键转换成对等的空格键
-b :在文字内有反斜杠 (/) 时,仅保留反斜杠最后接的那个字符
范例一:调用 cat -A 显示出所有特殊按键,最后以 col 将 [tab] 转成空白
[root@www ~]# cat -A /etc/man.config <==此时会看到很多 ^I 的符号,那就是 tab
[root@www ~]# cat /etc/man.config | col -x | cat -A | more
# 嘿嘿!如此一来, [tab] 按键会被取代成为空格键,输出就美观多了!
范例二:将 col 的 man page 转存成为 /root/col.man 得纯文本档
[root@www ~]# man col > /root/col.man
[root@www ~]# vi /root/col.man
COL(1) BSD General Commands Manual COL(1)
N^HNA^HAM^HME^HE
c^Hco^Hol^Hl - filter reverse line feeds from input
S^HSY^HYN^HNO^HOP^HPS^HSI^HIS^HS
c^Hco^Hol^Hl [-^H-b^Hbf^Hfp^Hpx^Hx] [-^H-l^Hl
_^Hn_^Hu_^Hm]
# 你没看错!由于 man page 内有些特殊按钮会用来作为类似特殊按键与颜色显示,
# 所以这个档案内就会出现如上所示的一堆怪异字符(有 ^ 的)
[root@www ~]# man col | col -b > /root/col.man
join
join 看字面上的意义 (加入/参加) 就可以知道,他是在处理两个档案之间的数据, 而且,主要是在处理『两个档案当中,有 "相同数据" 的那一行,才将他加在一起』的意思。我们调用底下的简单例子来说明:
[root@www ~]# join [-ti12] file1 file2
选项与参数:
-t :join 默认以空格符分隔数据,并且比对『第一个字段』的数据,如果两个档案相同,则将两笔数据联成一行,且第一个字段放在第一个!
-i :忽略大小写的差异;
-1 :这个是数字的 1 ,代表『第一个档案要用那个字段来分析』的意思;
-2 :代表『第二个档案要用那个字段来分析』的意思。
范例一:用 root 的身份,将 /etc/passwd 与 /etc/shadow 相关数据整合成一栏
[root@www ~]# head -n 3 /etc/passwd /etc/shadow
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
==> /etc/shadow <==
root:$1$/3AQpE5e$y9A/D0bh6rElAs:14120:0:99999:7:::
bin:*:14126:0:99999:7:::
daemon:*:14126:0:99999:7:::
# 由输出的资料可以发现这两个档案的最左边字段都是账号!且以 : 分隔
[root@www ~]# join -t ':' /etc/passwd /etc/shadow
root:x:0:0:root:/root:/bin/bash:$1$/3AQpE5e$y9A/D0bh6rElAs:14120:0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin:*:14126:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:14126:0:99999:7:::
# 透过上面这个动作,我们可以将两个档案第一字段相同者整合成一行!
# 第二个档案的相同字段并不会显示(因为已经在第一行了嘛!)
paste
这个 paste 就要比 join 简单多了!相对于 join 必须要比对两个档案的数据相关性, paste 就直接『将两行贴在一起,且中间以 [tab] 键隔开』而已!简单的使用方法:
[root@www ~]# paste [-d] file1 file2
选项与参数:
-d :后面可以接分隔字符。预设是以 [tab] 来分隔的!
- :如果 file 部分写成 - ,表示来自 standard input 的资料的意思。
范例一:将 /etc/passwd 与 /etc/shadow 同一行贴在一起
[root@www ~]# paste /etc/passwd /etc/shadow
bin:x:1:1:bin:/bin:/sbin/nologin bin:*:14126:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:14126:0:99999:7:::
adm:x:3:4:adm:/var/adm:/sbin/nologin adm:*:14126:0:99999:7:::
# 注意喔!同一行中间是以 [tab] 按键隔开的!
范例二:先将 /etc/group 读出(用 cat),然后与范例一贴上一起!且仅取出前三行
[root@www ~]# cat /etc/group|paste /etc/passwd /etc/shadow -|head -n
3
# 这个例子得重点在那个 - 的使用!那玩意儿常常代表 stdin 喔!
expand
这玩意儿就是在将 [tab] 按键转成空格键啦~可以这样玩:
[root@www ~]# expand [-t] file
选项与参数:
-t :后面可以接数字。一般来说,一个 tab 按键可以用 8 个空格键取代。我们也可以自行定义一个 [tab] 按键代表多少个字符呢!
范例一:将 /etc/man.config 内行首为 MANPATH 癿字样就取出;仅取前三行;
[root@www ~]# grep '^MANPATH' /etc/man.config | head -n 3
MANPATH /usr/man
MANPATH /usr/share/man
MANPATH /usr/local/man
# 行首得代表标志为 ^ ,这个我们留待下节介绍!先有概念即可!
范例二:承上,如果我想要将所有的符号都列出来?(用 cat)
[root@www ~]# grep '^MANPATH' /etc/man.config | head -n 3 |cat -A
MANPATH^I/usr/man$
MANPATH^I/usr/share/man$
MANPATH^I/usr/local/man$
# 发现差别了吗?没错~ [tab] 按键可以被 cat -A 显示成为 ^I
分割命令: split
如果你有档案太大,导致一些携带式装置无法复制的问题,嘿嘿!找 split 就对了! 他可以帮你将一个大档案,依据档案大小或行数来分割,就可以将大档案分割成为小档案了! 快速又有效啊!真不错~
[root@www ~]# split [-bl] file PREFIX
选项与参数:
-b :后面可接欲分割成的档案大小,可加单位,例如 b, k, m 等;
-l :以行数来进行分割。
PREFIX :代表前导符的意思,可作为分割档案的前导文字。
范例一:我的 /etc/termcap 有七百多K,若想要分成 300K 一个档案时?
[root@www ~]# cd /tmp; split -b 300k /etc/termcap termcap
[root@www tmp]# ll -k termcap*
-rw-r--r-- 1 root root 300 Feb 7 16:39 termcapaa
-rw-r--r-- 1 root root 300 Feb 7 16:39 termcapab
-rw-r--r-- 1 root root 189 Feb 7 16:39 termcapac
# 那个档名可以随意取的啦!我们只要写上前导文字,小档案就会以
# xxxaa, xxxab, xxxac 等方式来建立小档案的!
范例二:如何将上面的三个小档案合成一个档案,档名为 termcapback
[root@www tmp]# cat termcap* >> termcapback
# 很简单吧?就用数据流重导向就好啦!简单!
参数代换: xargs
xargs 可以读入 stdin 的数据,并且以空格符或断行字符作为分辨,将 stdin 的资料分隔成为 arguments 。
[root@www ~]# xargs [-0epn] command
选项与参数:
-0 :如果输入的stdin 含有特殊字符,例如 `, \, 空格键等等字符时,这个 -0 参数 可以将他还原成一般字符。这个参数可以用于特殊状态喔!
-e :这个是 EOF (end of file) 的意思。后面可以接一个字符串,当 xargs 分析到这个字符串时,就会停止继续工作!
-p :在执行每个指令的 argument 时,都会询问使用者的意思;
-n :后面接次数,每次 command 指令执行时,要使用几个参数的意思。看范例三。
当 xargs 后面没有接任何的指令时,默认是以 echo 来进行输出喔!
范例一:将 /etc/passwd 内的第一栏取出,仅取三行,使用 finger 这个指令将每个账号内容秀出来
[root@www ~]# cut -d':' -f1 /etc/passwd |head -n 3| xargs finger
Login: root Name: root
Directory: /root Shell: /bin/bash
Never logged in.
No mail.
No Plan.
......底下省略.....
# 由 finger account 可以取得该账号的相关说明内容,例如上面的输出就是
finger root
# 后的结果。在这个例子当中,我们调用 cut取出账号名称,用 head 取出三个
账号,
# 最后则是由 xargs 将三个账号的名称发成 finger 后面需要的参数!
范例二:同上,但是每次执行 finger 时,都要询问使用者是否动作?
[root@www ~]# cut -d':' -f1 /etc/passwd |head -n 3| xargs -p finger
finger root bin daemon ?...y
.....(底下省略)....
# 呵呵!这个 -p 的选项可以让用户的使用过程中,被询问到每个指令是否执行!
关于减号 - 的用途
管线命令在 bash 的连续的处理程序中是相当重要的!另外,在 log file 的分析当中也是相当重要的一环, 所以请特别留意!另外,在管线命令当中,常常会使用到前一个指令的 stdout 作为这次的 stdin , 某些指令需要用到文件名 (例如 tar) 来进行处理时,该 stdin 与stdout 可以调用减号 "-" 来替代,举例来说:
root@www ~]# tar -cvf - /home | tar -xvf -
上面这个例子是说:『我将 /home 里面的档案给他打包,但打包的数据不是记录到档案,而是传送到 stdout; 经过管线后,将 tar -cvf - /home 传送给后面的 tar -xvf - 』。后面的这个 - 则是取用前一个指令的 stdout, 因此,我们就不需要使用 file 了!这是很常见的例子喔!注意注意!
相关文章推荐
- Linux学习笔记(十二)软件安装
- Linux学习笔记(十二、选项帮助)
- Linux学习笔记(十二)--命令学习(用户创建、删除等)
- Linux学习笔记(十二)
- linux学习笔记(十二) mount命令详解
- 线性代数学习笔记(十二)
- Linux学习笔记--Tcpdump
- 实验十二_编写0号中断处理程序
- Makefile十二之make的运行
- Linux学习笔记——Ubuntu更新软件源
- WDA基础十二:FREE PROGRAM SH
- Linux学习笔记之文件管理,用户管理
- ConfigReader(十二)—— ReadGuideClickButtonTaskConfig
- hbase源码系列(十二)Get、Scan在服务端是如何处理?
- springboot学习笔记(十二) RestTemplate
- 设计模式之十二:Proxy(代理)—对象结构型模式
- Linux学习笔记(绝对/相对路径,cd命令,mkdir/rmdir,rm)
- springMVC3学习(十二)--文件上传优化CommonsMultipartResolver
- Gson教程十二(译):Float和Double类型的特殊值
- 程序员的无奈(十二):终于获得了投资