今天下了个名叫Z的压缩工具前端代码(版本2.7.1),读了下最大的感觉就是要学的东西还有好多呀~~~
这篇blog里记录了我是我阅读源码后总结的几个知识点
OSC上Z的页面地址:http://www.oschina.net/p/z
Z的官方地址:http://www.cs.indiana.edu/~kinzler/z/
1.Z的目录结构
下载下来的文件是z-2.7.1.tgz,通过下面这个命令解压缩
tar xzf z-2.7.1.tgz
可以看到的目录结构为(因为要格式对齐,所以下面引号里的文字采用了等宽字体andale mono)
z-2.7.1
|
|-COPYING |GNU GENERAL PUBLIC LICENSE Version 2, June 1991
|-Makefile |makefile文件
|-README |安装说明、GPL版权声明等
|-z |Shell脚本:压缩、解压缩程序
|-z.html |使用说明
|-z.man |使用手册
|-zzcat |Shell脚本:查看压缩包中的文件内容
这个目录中的两个Shell脚本分别是z和zzcat,z.man是手册,Makefile是安装脚本
关于手册的撰写与安装,可以参考:http://my.oschina.net/Tsybius2014/blog/356779
这篇blog中的笔记,都根据我在阅读z和zzcat两个脚本时中出现的疑惑总结的
2.export的使用
export可以用来设置环境变量,export的设置只对当前的会话有效。
export的语法为:`export 环境变量1 环境变量2 环境变量3 ...` (不同环境变量中间用空格隔开)
可以把export命令写到~/.bahs_profile和~/.bashrc中,这样可以在每一次登录后都加载这些环境变量
3.“.命令”与“:命令”
1)“.命令”用于在当前Shell中执行命令,如:
if [ -f /etc/bashrc ]; then . /etc/bashrc fi
意为如果/etc/bashrc是普通文件,则运行这个脚本
2)“:命令”是空命令,用于简化条件逻辑,如:
if [ $# -eq 0 ]; then : else echo "hello world" fi
意为如果输入参数个数不为0,则输出字符串“hello world”
4.shell中以符号“$”开头的变量
$$ # Shell本身的PID $! # Shell最后运行的后台Process的PID $? # 最后运行的命令的返回值 $- # 使用Set命令设定的Flag一览 $@ # 所有参数列表,以 $1 $2 $3 ... $n 的形式输出所有参数 $# # 添加到Shell的参数个数 $0 # Shell本身的文件名 $1~$n # 各个参数
5.set、env和export
1)set 显示当前shell的变量,包括当前用户的变量
2)env 显示当前用户的变量
3)export 显示当前导出成用户变量的shell变量
关于set命令,还有一点补充:
set ±x 执行指令后,显示/不显示该指令及所下的参数,下面两个截图显示了set +x与set -x的运行结果
1)set +x的情况
2)set -x的情况
6.shift命令平移参数
可以将原来的第一个参数删去,后面的参数排名依次向前顺移一位
下面这个图中,经过shift后,$1存储的是原来的$2,$2存储的是原来的$3,以此类推
这个命令,可以在读取一个脚本的输入参数时用到。通过while循环每次读取第一个参数,每读取一个参数,进行完相应操作后,就将它从参数表中删去。直到参数列表中没有参数时,所有参数处理完毕。就像下面这个代码段,实现的就是这个效果:
while : do case $# in 0) break;; *) case "$1" in -a) echo "-a";; -b) echo "-b";; -[0-9]) echo "$1";; -*) echo "unknown option ($1)" 1>&2;; *) break;; esac shift;; esac done
运行结果截图:
7.关于0、1、2对应的标准输入、标准输出、错误输出
标准的输入,输出和错误输出分别表示为STDIN,STDOUT,STDERR,也可以用0,1,2来表示。
默认的标准输入为键盘,默认的标准输出会输出到终端
`2>&1`,意为把错误输出重定向到标准输出,其他如`1>&2`等,解读的方式相同,意为标准输出重定向到错误输出
8.case语句中的*与?*
case语句中,*代表任意字符,?*代表任意字符但无字符的情况除外
# * in case echo "situation 1:" case "$1" in *) echo "hello world" esac # ?* in case echo "situation 2:" case "$1" in ?*) echo "hello world" esac
这个脚本如果不带任何参数,执行结果为
可以看到,当第一次执行脚本时,$1为空串,这个时候不能通过?*的匹配,但是能通过*的匹配
9.cat与EOF组合可以打印多行文本
cat与EOF一起用,可以打印其中的多行文本,大段的提示信息,可以用这个方法打印
cat << EOF hello world 2014/12/18 -Tsybius EOF
打印的结果为:
10.Shell中的AND(&&)和OR(||)
1)&&的用法:command1 && command2 [&& command3 ...]
★ 命令之间使用 && 连接,实现逻辑与的功能
★ 只有在 && 左边的命令返回真(命令返回值 $? == 0),&& 右边的命令才会被执行
★ 只要有一个命令返回假(命令返回值 $? == 1),后面的命令就不会被执行
2)||的用法:command1 || command2 [|| command3 ...]
★ 命令之间使用 || 连接,实现逻辑或的功能。
★ 只有在 || 左边的命令返回假(命令返回值 $? == 1),|| 右边的命令才会被执行
★ 只要有一个命令返回真(命令返回值 $? == 0),后面的命令就不会被执行
11.trap命令处理信号
trap命令可以指定脚本如何处理信号,语法为
trap `commands` signals
其中commands为接收到信后后执行的命令(多个命令则中间用分号隔开),signals是信号对应的数字。例如:
trap `exit 4` 1 2 13 15
所有的信号可以通过命令 `trap -l` 查到,我的RedHat上查到的结果是:
12.关于for循环中的arg和file
如果没有指定arg和file属于哪里,那arg和file将会从#@中取值,即从所有输入参数中取值
echo "situation 1" for arg do echo $arg done echo "situation 2" for file do echo $file done
这个脚本的执行结果为:
13.关于if语句的几个知识点
1)if语句后面接test和判断条件,与if语句后面接方括号内置判断条件,是完全等价的
即下面两段代码作用等价(XXX为表达式)
if test XXX; then : fi
if [ XXX ]; then : fi
2)==、!=、>、<等符号,左右两侧表达式与符号间需要至少一个空格
3)shell脚本中使用括号要用进行转义,使用'\('和'\)',括号可以提升括号内表达式的运算优先级
4)-a代表逻辑与(and的第一个字母),-o代表逻辑或(or的第一个字母)
echo $@ if test $1 != $1 -a \( $2 == $2 -o $3 == $3 \); then echo x fi if test \( $1 != $1 -a $2 == $2 \) -o $3 == $3; then echo y fi if test $1 != $1 -a $2 == $2 -o $3 == $3; then echo z fi
这段脚本的运行结果如图:(第一个if后面的表达式为假,后两个表达式都为真)
14.关于umask命令
umask主要用于,在创建新文件或目录时,屏蔽掉新文件或目录不应有的访问允许权限
umask屏蔽的规则如下:
1)不管屏蔽码是多少,新创建的文件默认不具有可执行允可权限,新创建的目录默认具有可执行允可权限
2)屏蔽码的格式为八进制格式,共三个八进制数
3)其中的每一个八进制数由三位表示,分别是读、写、执行
4)产生的文件权限为umask值求反后的值,如022取反后是755
还有一个更改文件和目录权限的命令是chmod
END