TODO: 添加12,13章未完的命令的参数
第12章 外部命令
1. 基本命令:
(1) ls -R 递归 -F在文件后加类型标识 -S按照文件大小排列 -t按文件修改时间排列 -i打印inode号 --time=atime/ctime,默认不写就是mtime
(2)tac 和cat相反,从最后一行读取文件
rev 反转每一行里的字符,但行的读取顺序还是从文件头开始,比如123变为321
(3)cp -a 等于-dpR,因为一般的不加p的cp,就是read读取文件内容,然后write到目的地,这个目的文件的创建后的owner和权限等于该用户自己创建一个文件的权限。如果你想保持原有的文件owner和权限,即让ls -l显示出来的一样,就要用p,为了对目录递归和文件都有用,所以加dR,于是cp提供了-a这个简洁的参数。
(4)find /dir -exec cmd {} \; 好吧,这个上面已经好多例子了,经常还用-type限制文件类型,-name限制文件名,-inum限制inode号,-mtime/-ctime/-atime限制访问时间(-mtime上次文件内容修改时间,-ctime上次inode修改时间(所有-mtime改变,-ctime跟着变),-atime上次访问内容的时间,比如cat一个文件)。
另外,可以用 -regex 来使用正则式匹配文件名
(5)xargs
xargs就是专门拿来构造命令的,主要采用以下两种用法:
ls | xargs -n2 diff 这样的话,xargs会把标准输入,这里就是ls了,把标准输入两个两个一组,调用diff,给它两个参数。比如ls 为 a.txt b.txt c.txt d.txt的话,结果就是两次diff调用:diff a.txt b.txt; diff c.txt d.txt
ls | xargs -I {} mv {} {}.old 这样的话,将当前目录下所有文件末尾加上.old。-I 的作用是引出{},表示后面遇上{},就把参数填入。这里没有用-n,所以,默认是传给mv一个参数。
另外,其实xargs常用到find里,这时,只需要用 find ... -print|xargs ... 即可。比-exec方便。注意,-exec现在的实现,也是一个参数调用后面命令一次,并不是把所有参数堆到一起,再执行命令。且,如果用-exec来达到-I的效果,是一样的,比如 -exec mv {} {}.old
(6)expr 再研究
(7)date +要放在格式前,+%s表示unix秒数,+%j表示今天是今年第几天。date也可以设置时间 date -s '20060927 10:03:00'。还常用做墙上时间和绝对秒数之间的转换: date -d "1970-1-1 UTC 212121221 seconds" +"%Y-%m-%d %T %z" 就是把秒数转换为墙上时间,date -d "2009-06-16 09:30:00" +"%s" 反过来也一样。如果是绝对天数,那么把其中的seconds改为days
(8)touch 还得提一下,touch改变的是mtime/ctime/atime三个时间!!它的作用是,用一个不用的文件,来keep比如某个目录最后一次xxx的时间。比如简单的记录一个项目的修改时间。
(9)at 很easy的,at 时间 然后敲回车,输入你想要执行的命令,最后按ctrl-d结束。时间可以是"14:30 Friday" "23:20 today" 形式等。也可以用-f指定命令文件。
(10)cal 日历
(11)sleep 可以以分,小时,天为单位:sleep 3 h 睡3小时
(12)usleep micro second的sleep
2. 文本处理
先来看个经典例子:
cat $* | # Contents of specified files to stdout.
tr A−Z a−z | # Convert to lowercase.
tr ' ' '\012' | # New: change spaces to newlines.
#tr −cd '\012[a−z][0−9]' | # Get rid of everything non−alphanumeric
#+ (original script).
tr −c '\012a−z' '\012' | # Rather than deleting
#+ now change non−alpha to newlines.
sort | # $SORT options unnecessary now.
uniq | # Remove duplicates.
grep −v '^#' | # Delete lines beginning with a hashmark.
grep −v '^$' # Delete blank lines.
再看一个经典的变形:
cat hehe.txt |tr ' ' '\n'|grep -v '^$'|sort|uniq -c|sort -nr
尤其是后面的 sort|uniq -c|sort -nr 是很常用的组合。-n是书上加的,不知道只写-r有什么不妥。
(1)sort -r 反向 -m 将两个已经排好序的文件合并成排序的文件
(2)uniq 去掉相邻的重复项, -c在行首打印重复次数
(3)expand,unexpand 把tab转换为空格,和相反转化
(4)cut 就是awk '{print $n}'的简化版。 cut -d ':' -f1,2,3 表示打印1,2,3列,分割符是:. 还有个有用的是 -c1-10 表示只打印每一行的1到10个字符,这可以用于提取连续字段中某一段。
(5)paste: 将文件2接到文件1中,接的方法有两个,默认是把2中的每行接在1中的每行后。如果用-s,则是将文件1的所有行以tab隔开,做为一个新行,将文件2的所有行也做为一个新行,结果就是两行。用-d可以指定分割符。paste也经常和cut用于log系统。
(6)join: 被认为是paste的堂兄,它做的事情有时更有意义: 大循环是遍历文件1中的行,小循环是对文件1中的某行,来遍历文件2中的所有行。当文件2中的行的第一个字段和文件1中的行的第一个字段相同时,把它接在文件1中的行后,但是去掉第一个字段,也就是新行只有一个“第一个字段”。多用于两个文件,有相同的关键字的行的整合。类似数据库操作。
(7)head: -c2 打印文件前面2个字符 -n 打印文件前面n行
(8)tail: 和head完全相同。注意有个-f参数很有用 tail -f /logfile 如果logfile被append了,它就会输出被append的东西。我用>>来append是有用的,但是用vim来append是没有用的。
(9)grep: -i 忽略大小写 -l 打印匹配的文件而不是行 -r 递归 -n 附带打印行号 -v 过滤掉某行 -c 打印匹配数 ———— 还是尽量用egrep吧,它等于grep -E,它支持多一些正则式,比grep好用些。另外,如果要搜索.gz压缩文件,还是用z打头的,如zgrep,zegrep吧。比如一个文件夹下面普通文件和压缩文件都有,那么用zgrep,zegrep更方便些。如果是.bz2文件,用bz打头的,如bzgrep,bzegrep。
另外,grep常用做条件测试,判断一个字符串是否满足要求,因为如果匹配,它返回0。
(10)look: 就是简单的grep, look string file 是返回以string开头的file的行。所以它是为字典查找设计的,就是看行首的字节。
(11)wc: wc有个很大的好处,可以得到多个文件的总字节数. wc [d-h]* | grep total | awk '{print $3}'就可以了。其他重要的,-w单词数 -l 行数 -c字节数 -L最长行的长度,这些可以计算一个命令的输出内容。
(12)tr: 它需要用<filename来操作文件。除了常用的两参数模式,如tr "A-Z" "a-z"<filename把大写转换为小写外,还有其他有用选项。-d "0-9" 单参数,去掉文件中的数字,-s 'x' 去掉连续的x,但保留第一个,比如用于去掉多余空格。-c取反,tr -c "b-d" "+" 表示不是b-d的才替代为+。 好吧,tr 'a−zA−Z' 'n−za−mN−ZA−M',居然也可以,就是把任意一个序列转换为任意对应的字符。
(13)fold: 用于断行,-s 断行,但是只在发现空格的地方。-w限制一行长度,是硬断行
(14)fmt: 也用于断行,这个比fold好用一点,直接 fmt -w 2 表示如果该行的长度大于2,那么遇到空格就得换行。这个很人性化。
(15)col: 暂不研究
(16)column: 这个就很有用了,制作漂亮对齐的表格。比如你想给表格加个头,想让头和内容能对齐:
(printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG−NAME\n" \ ; ls -l | sed 1d) | column -t
这里printf和ls的输出,要一起经过column处理,所以用()启动一个子shell,之后column 的-t会把每一列对齐!! -t就是制作table的意思,是最常用的。
(17)colrm: 删除指定的列——这个列指字符,不是靠空格等分割的列。colrm 2 4 < filename 表示删除2到4列,其他的输出到屏幕
(18)nl: cat -n是给每一行加上行号,nl是给每一个非空行加上行号,但是空行也会打印
(19)pr: 能够将较大的文件分割成多个页面,并为每个页面添加标题。主要用于得到适合打印的文本。功能很强大,是nl, paste, fold, column, expand的超集。
(20)gettext: 暂不研究,和localization相关
(21)msgfmt: 赞不研究,和localization相关
(22)iconv: 修改文件内容编码 iconv -f gbk -t utf8 a.html -o b.html 它的兄弟命令是convmv,修改文件名编码, convmv -f gb2312 -t utf8 -r --notest *(如果不加notest,则不会做实际转换)
3. 文件和打包:
------------ 打包 -------------
(1)tar
(2)ar rcs
(3)rpm
(4)cpio,rpm2cpio
(5)gzip,bzip2: -d表示解压。我想说,没有找到直接压缩多个文件的做法,只能先用 tar打包后再压缩。所以,如果是多个文件用tar打包的话,你用zcat,bzcat打印出的东西,除了每个文件的内容外,还会含有tar维护的信息,如owner,权限... zcat,bzcat等于 -dc
(6)zip,unzip: 这两个,其实是tar和gzip的结合,即可以压缩多个文件。它也是Internet上常见的那种zip。
------------ 文件信息 -----------
(1)file: 比如告诉你ASCII text,或者UTF-8 Unicode text
(2)which: 可执行文件的路径
(3)whereis: 居然可以找各种文件...包括资源文件和man文件
(4)readlink: 和ls -l最后一列信息相同
(5)strings: 提取一个二进制文件中的printable信息,比如能让你容易判断一个文件类型,比如一个图片里有JFIF,则多半是一个JPEF文件。
------------ 比较 -----------
(1)diff,patch
<< 基本用法 >>
生成和打补丁:(记忆方式和cp,ln类似,从dir生成dir2,需要名为dir1-to-dir2.patch的补丁文件)
diff -uNr dir1 dir2 > dir1-to-dir2.patch # 对目录下所有文件生成补丁
patch -p0 < dir1-to-dir2.patch # patch时在dir1,dir2所在目录下
patch -p1 < ../dir1-to-dir2.patch # patch时在dir1所在目录下(p0和p1就这区别)
patch -p1 -R < ../dir1-to-dir2.patch # patch时在dir1所在目录下(p0和p1就这区别),将变为file2的file1,再变回来
diff -uN file1 file2 > file1-to-file2.patch # 对文件打补丁
patch -p0 < dir1-to-dir2.patch # patch时在dir1,dir2所在目录下
patch -p0 -R < dir1-to-dir2.patch # patch时在dir1,dir2所在目录下,将变为file2的file1,再变回来
说明:
其中 -u 表示生成补丁文件的格式,那个文件格式很好懂得,-表示准备去掉的行,+表示准备加上的行,其实就说明了两个文件间的差异。它和vimdiff不一样,vimdiff是在两个窗口中对比那一行,而diff的-u输出是patch文件中用-和+,上下来看。而且用diff比vim的好处是,可以一次性递归列出所有文件的所有要改的地方。其实在比如codereview的时候,很方便。-r表示递归。-N加上把,不太懂。patch时候,-R表示把变为file2的file1再变回来。
另外,patch时候,加个--dry-run的话,就能够只显示将要patch的文件,而不会真正patch.
<< 只用diff找出两个文件夹下独有的文件名 >>
diff -r dir1 dir2 |grep Only
<< 只用diff找出两个文件夹下独有的文件名,和内容不同的文件 >>
diff -rq dir1 dir2 # -q 只说明两个文件不同,不显示差异
(2)cmp: 简单diff,只显示第一处不同的地方
(3)comm: 打印三列: 文件1独有的,文件2独有的,两文件共有的行
------------ 小工具 ------------
(1)basename & dirname:将文件名和路径名从全路径中抽取出来。
(2)split: 用于分割大文件
(3)md5sum
(4)shred: 用于乱涂一个文件。即你想删除一个文件,但是如果直接用rm来删,会使得别人容易从硬盘恢复,所以先用shred搞乱。
(5)mktemp: 用于在某目录下生成唯一的文件,mktemp /tmp/hah.XXXXXX 注意,XXXXXX你可以随便添加多少个X,它会被mktemp转换为唯一的字符串
------------ 编码 -------------
(1)uuencode,uudecode: 在二进制和ASCII码间相互转换
(2)mimencode,mmencode: 同上,针对的是多媒体文件
4. 通信工具
(1)host,dig 从DNS服务器获取信息,典型的如DNS查找(域名->IP)和反向查找(IP->域名)等功能。
比如反向:
dig www.google.com 你会看见google的ip地址, dig -x googleip地址 你会看见google域名,在最后,你会看到SERVER就是你本次查询的服务器。
(nslookup已经过时了,因为它没有dig灵活)
(2)... 好多命令,以后研究
5. 终端控制命令
(1)... 好多命令,以后研究
6. 数学命令
(1)... 好多命令,以后研究
7. 更多命令
(1)jot,seq
(2)...
第13章 系统管理命令
---------- 用户和组 ------------
(1)groups: 后跟用户名,列出用户所属的所有组
(2)chown,chgrp: 改变文件的用户或组
(3)id: 后跟用户名,列出用户的uid,gid,所属组等信息
(4)who: 打印所有终端上目前的登录信息
(5)w: 等于who加终端上跑的进程,包括tty的和pts的
(6)logname: 当你su后,whoami显示是root,但是logname还是你自己
(7)last: 显示登录过的用户,最近登录的排在最前面,包括当前还活跃的。
(8)gpasswd: gpasswd -a <user> <group_name>为组添加用户,换为-d就是从组里删除用户
(9)useradd,userdel,groupadd,groupdel 参数比较easy
(10)pgrep,pkill: pgrep -u fengyi -t pts/1 可以找出fengyi用户在终端pts/1上的所有进程!! 输出是纯粹的pid号,如果你加-l,就一块列出进程名。如果参数中你给了进程名,就只列出那个进程的pid,但是如果你加了-u和-t指定用户名和终端,则可能找不到匹配的呵呵。 注意,-u后面跟的是effective uid,如果要跟real uid,用-U。 另外,pkill和pgrep参数一样,不同的是,它不是列出那些进程号,而是给那些进程发送你规定的信号!! 这个可方便了,比如杀死所有的某种进程。
---------- 终端相关 ------------
(1)wall: 向所有终端发信息
(2)dmesg: 打印系统启动的信息
(3)好多,暂时不研究
---------- 信息和统计 -----------
(1)lsof: 列出opened files,以及打开它的命令,用户等信息
(2)strace: 后接可执行文件名,列出该命令的含有的系统调用。
(3)free: 列出memory,cache和swap的信息
(4)stat: 列出一个文件的n多信息,相当于ls能得到的所有信息的汇总
(5)vmstat: 列出虚拟内存的信息
(6)uptime: 列出系统从启动为止到现在的时间
(7)readelf,ldd:读取二进制文件信息
(8)好多,暂时不研究
----------- 系统日志 ------------
(1)logger: 就是syslog的命令版。注意要指定facility和priority
(2)
----------- 任务管理 ------------
(1)pidof: pidof接程序名,列出所有运行它的进程PID。
(2)
----------- 系统控制和启动 ----------
(1)init... 暂时不研究
------------ 网络 ---------------
------------ 文件系统 -------------
----------- 备份 -------------
----------- 系统资源 ----------
----------- 模块 ------------
----------- 其他 ------------
at命令用法:“at -f shell文件 时间” 就会在时间执行shell文件。如果不用 -f 引出文件,那么就 “at 时间”,然后at会提示你输入命令,每一行输入你想执行的命令即可。完了,按Ctl-D输入结束。用 atq 可以查看等待执行的任务。用atrm可以删除某一任务。 比较郁闷的是,在ubuntu9.04上,只有一些命令可以被at执行,比如touch,但是mplayer却不行? 但是在ubuntu8.10上,什么命令都可以跑。另外注意,at有配置文件在 /etc/at.allow 和 /etc/at.deny,一般不用管,但是需要控制用户使用at的权限时,就要用了。
第14章 命令替代
这一章意思就是,一个变量值,可以用``或$()来从命令获取。这里唯一值得提的是:while for if等同样是命令,里面需要含有echo语句,如下:
variable1=`for i in 1 2 3 4 5
do
echo −n "$i" # The 'echo' command is critical
done` #+ to command substitution.
echo "variable1 = $variable1" # variable1 = 12345
第15章 算术运算
在前面已经说了,这里重复一下,有三种,$(()),let 和 expr。其中$(())以前我爱用,let用得少,但确实好用,expr用的少。
第16章 I/O重定向
这一章已经比较熟了,只有一些要说明如下:
&>filename 表示重定向0和1两个都到filename.
打开文件,读写导致位置移动!!!虽然没有seek,tell
echo 1234567890 > File # Write string to "File".
exec 3<> File # Open "File" and assign fd 3 to it.
read −n 4 <&3 # Read only 4 characters.
echo −n . >&3 # Write a decimal point there.
exec 3>&− # Close fd 3.
cat File # ==> 1234.67890
说明:这里的两个exec是用于打开和关闭文件,相当于open和close,打开时为之赋予你需要的描述符,这里是3,关闭时也是关闭3。里面的read会导致游标移动,使得echo(想当于write)写出的位置发生变化。(这里的两个exec不会导致shell被替换掉,无语)。更多的关于关闭文件描述符的介绍,见P251。
多个重定向的书写顺序:
ls -z 2>&1 >>cow.txt 这个试图把-z这个错误选项的错误信息输出到cow.txt,但是不成功,还是打印到了终端上,这是因为,这里的逻辑是:被依赖的写前面。显然,这里是2>1>cow.txt,这里有两个管道,一是2>1,二是1>cow.txt,前者依赖于后者,所以,需要你把后者写前面。这样就对了:ls -z >>cow.txt 2>&1
exec的作用:
(1)打开和关闭文件:上面已经说了
(2)重定向本shell中的描述符:典型应用是,不必要为每个read或其他从stdin输入的命令都做重定向到文件,而是在前面用一次exec即可。这样方便对文件的处理。对于echo等输出命令,也是同理的。比如对read来说,可以这样:
exec 6<&0 #dup 0 到6,6用做0的临时存储地
exec < data-file #重定向0到文件
... #各种read或其他命令来处理文件,典型的用法是不断read,来提取文件每一行,然后用sed/awk处理。但这里其实我们在上面的while循环中已经做了对while的重定向了,即在while/for/until/if等的最后(比如done后)加个< filename 即可以达到类似的目的,已经可以达到取出每一行,然后来处理。(插一句,函数居然也可以被重定向!可能因为他们都是代码块的缘故)
exec 0<&6 6<&− #把6 dup回来到0,并关闭6
(3)代替本shell,执行一个命令,就是一般用法。
第17章 here文档
here文档,就是型如下面的文档:
#!/bin/bash
interactive−program <<LimitString
command #1
command #2
...
LimitString
作用是将一系列命令喂给interactive-program。这行为是shell的行为,即如果你写interactive-program < limitString,shell会以为你的输入来自limitString文件,但是如果你写 << limitString,shell就会以为你要开始喂命令了,并将limitString理解为命令的结束标志,这样,你就可以不断写命令了,一行一行的,直到你写了limitString敲个回车,这时,shell才把你的命令给interactive-program,当然你写的有空格就有空格,每一行都有换行,把这整体给program.然后就看program怎么理解这些输入了,一般的program是一次读一行型的,所以正好可以!(这里“命令”的意思,不一定是命令,也可能是一般的输入等待处理,比如你用 cat << cow 试试)
典型例子:登录ftp服务器,并打印目录信息:注意用到变量:
cmd=ls
ftp -n openware.byr.edu.cn << endofcmd
user anonymous anonymous
$cmd
bye
endofcmd
但是,如果endofcmd被加了引号,那么里面的所有的特殊字符都无效了。
cmd=ls
ftp -n openware.byr.edu.cn << 'endofcmd'
user anonymous anonymous
$cmd #这里实际是无效的,ftp服务器会收到"$cmd"而已,而不是ls
bye
endofcmd
函数也被当成上面的interactive-program一样来用!!!
最后,作者提到,对于太复杂的东西,还是用expect来做更easy。
其实以前我是用管道来做的,效果一样。管道的左边是一个函数或者shell脚本即可,右边是ftp等交互式命令。
第18章 纯属搞笑
五、高级主题
第19章 正则表达式
1. 正则式RegularExpressions(RE):
用于sed,awk,egrep(好多对于grep不适用),其实挺简单,记住如下这些即可应付大多数场合,要提醒的是,以下以awk为准,其中有些元字符在sed,egrep中要用的话,得加\来转义,如+
把\D加进去,看看上次百度笔试后晚上下的文档,补充一下!!!!!!!!!!!!!!!!!!!!!!!!
(1) 基本RE:
.任何一个字符,除了newline
*和前面的连用,表示出现0次或多次
^$匹配空白行
[xyz] 匹配x,y或者z
[c-n] 匹配c-n范围内的所有字符
[B-Pk-y] 匹配B-P和k-y范围内的所有字符
[a-z0-9] 匹配小写字符或者数字
[^b-d] 匹配b-d范围以外的字符
\<the\> 匹配the单个单词,不包括them之类的
(2) 扩展RE:
?和前面的连用,表示出现0次或1次
+和前面的连用,表示出现1次或多次
\{5\}和前面的连用,表示出现5次
(re1|re2|re3)表示或者是re1,或者是re2,或者是re3,即()里写正则式组
(3) POSIX RE:
[:alnum:] This is equivalent to [A−Za−z0−9].
[:alpha:] This is equivalent to [A−Za−z].
[:blank:] matches a space or a tab.
[:cntrl:] matches control characters.
[:digit:] matches (decimal) digits. This is equivalent to [0−9].
[:graph:] (graphic printable characters). Matches characters in the range of ASCII 33 − 126. This is the same as [:print:], below, but excluding the space character.
[:print:] (printable characters). Matches characters in the range of ASCII 32 − 126. This is the same as [:graph:], above, but adding the space character.
[:space:] matches whitespace characters (space and horizontal tab).
[:lower:] This is equivalent to [a−z].
[:upper:] This is equivalent to [A−Z].
[:xdigit:] matches hexadecimal digits. This is equivalent to [0−9A−Fa−f].
不过,使用的时候,要再加个[],如grep [[:digit:]] test.file
2. globbing:shell不理解正则式,它只是做通配符的扩展
通配符如下:
*0个或多个任意字符。
?1个任意字符,提醒的是*和?不再和前面的连用,而是单独使用。
[^abc]用法同正则式
{通配符1,通配符2,通配符3} 这等于RE中的() 注意,这里,两边没有空格,且至少要放入两个通配符,或者{通配符1,}式,即有,号
如:ls -l|egrep '(cow\.|hehe\.)' 等于 ls -l {cow.*,hehe.*}
shell的有两个要点提示如下:
(1)匹配什么就要写全,比如c,只能匹配到c,而 c*,匹配不到 bc,这点和RE不一样,RE只需要含有要匹配的字符串的一部分即可。
(2)单独的*不能匹配以.开头的文件。除了借助egrep,sed,awk来找外,可以这样:
ls {.[^.]*,..?*} 这表示匹配.abc,或者..dd之类的文件。
第20章 子shell
在上面介绍wait的时候,已经写了用子shell来做并行计算了。这里清晰一个概念:
用()括起来的子shell执行码,如果不加&的话,和普通执行的区别是:原shell会启动一个子shell来执行这段代码,所以你可以随意改东西,比如环境变量等!!注意的是,同启动一个子进行来执行命令一样,原shell会等待子shell结束后再执行。所以,你要并行计算的话,就加&吧。
第21章 限制的shell
当你用set -r时,就把shell置于了restricted状态,在这个状态下,一些命令如cd,一些操作,如重定向是不起作用的,具体不起作用的东西见P279列出的。
目的是防止可能的damage to system
第22章 进程替代
就和命令替代一样,意思是将进程的输出赋值给一个变量,语法上见P281
第23章 函数
下面第一个最常用:
function_name () {
command...
return(可选,如果不写,返回的就是最后一个命令的退出码)
}
或者
function_name ()
{
command...
return
}
或者
function function_name {
command...
return
}
然后用名字直接调用即可,如 function_name arg1 arg2
参数的话,在函数里用$1,$2来引用即可,()里不需要写什么
另外,为了得到返回的东西(不是函数return的),方法是在函数里直接写变量,这个变量默认就是全局的,然后在函数外面直接得到之即可。
但是,局部的变量呢,必须要用local声明,如local var=20。局部变量的好处是,使得递归成为可能。
另外,注意,函数这种代码块,也可以用管道和<,>来操作。
第24章 Aliases
easy阿
第25章 List Constructs
这一章讲的是用 cmd1 && cmd2 && cmd3 ... 和 cmd1 || cmd2 || cmd3 ... 来替代if/then, case之类的。简单的还可以用这个,复杂的真不好看。
规则是:
cmd1如果为假,就不会走 cmd1 && cmd2 && cmd3 中的cmd2和cmd3
cmd1如果为真,就不会走 cmd1 || cmd2 || cmd3 中的cmd2和cmd3
第26章 数组
还是别看了,太多了,见前面提到的基本的即可。
注意的是,为了实现一些本该用C实现的算法,在shell里用数组往往更容易。
第27章 基本文件
1. startup file
/etc/profile Bourne模式的shell,如bash的设置文件
/etc/bashrc Bash的设置文件
$HOME/.bash_profile 是/etc/profile的本地版
$HOME/.bashrc 是/etc/bashrc的本地版
上面,只有/etc/profile 是在非login shell(如gnome-terminal)中无效的。其他的在login shell和非login shell中都有效。
2. logout file
$HOME/.bash_logout 用户从login shell退出的时候被执行
第28章 /dev和/proc
这一章也就是大概提了下:
1. /dev
/dev/loop0 称为loopback设备,以前曾经把一个文件,mount到/tmp下,就是先在文件中创建文件系统,再借助/dev/loop0,具体查阅以前文档。
/dev/null, /dev/zero,具体见29章. /dev/urandom 上面已经介绍了。
2. /proc
(1) 一大堆文件
cat /proc/devices
cat /proc/interrupts
cat /proc/partitions
cat /proc/loadavg
cat /proc/filesystems
cat /proc/version
cat /proc/cpuinfo
(2) 进程特定文件夹
在proc下有许多数字文件夹,每个文件夹都是一个进程PID。
里面有这个进程的信息文件,主要感兴趣的文件有下面四个:
stat/status 含有进程的统计信息,用数字表示,但是这每个数字的意思我还不清楚
cmdline 含有这个进程被invoke时给的参数
exe 这是一个指向执行文件的链接,用ls -l可得知可执行文件的位置。
书上给了两个例子,一是通过进程号查找进程的启动程序的目录,通过/proc/pid/exe,很easy。另一个是通过进程名,先用ps ax得到进程号,然后再同样查找/proc。
第29章 /dev/null 和 /dev/zero
/dev/null 这个就是黑洞,写了就被丢弃,读是读不出来的。所以,除了常见的重定向外,其实还可以把它链接到任何你不想存的文件。比如一个程序喜欢把你认为无用的东西写到一个文件,导致占用空间,那你可以把这个文件删掉,再链接/dev/null到这个文件。
/dev/zero 用于初始化文件为全0(数字0),包括初始化设备。典型的应用是初始化一个swap文件为全0。然后swap才能被swapon。典型的是用 dd if=/dev/zero of=... 来从/dev/zero中取出你需要个数的0。
第30章 Debugging
好吧,不看了... 不过这一章介绍了trap的用法。
第31章 bash Options
这一章 介绍了通过set设置的bash选项,以及如果影响脚本。
第32章 Gotchas
把保留字赋给变量,比如把case这个赋给变量??不看了...
第33章 脚本风格
打点...
第34章 Miscellany
各种小主题...
第35章 Bash,version 2
介绍了version 2特性
第36章 Endnotes
over...