Bash 编程

Bash 编程 
一.Bash特殊字符 
1.通配符: 
*:匹配任何字符串 
?:匹配任何单个字符 
集合运算符:用一些单个字、一个连续范围或断续的字符集合作为通配符 
[set]:用字符集合作通配符匹配单个字符,如:[aeiou],[a-o],[a-h, w-z] 
[!set]:除了集合外的所有字符组成的集合作通配符 
2.花括号展开式(可以嵌套): 
格式:[前导字符串]{字符串1[{嵌套字符串1…}] [, 字符传2…]}[后继字符串] 
如:c{a{r, t, n}, b{r, t, n}}s 就等于 cars cats cans cbrs cbts cbns 
3.其它特殊字符: 
<:输入重定向 
>;:输出重定向(没有文件则创建,有则覆盖) 
>;>;:输出重定向(没有则创建,有则追加到文件尾部) 
(:子shell开始,子shell继承父shell部分环境变量 
):子shell结束 
{:命令块开始,由当前shell执行,保留所有环境变量 
}:命令块结束 
|:管道 
\:引用后面的单个字符 
‘:强引用字符串,不解释特殊字符 
“:弱引用字符串,解释所有特殊字符 
~:根目录 
`:命令替换 
;:命令分隔符(命令终止符),运行在一行里执行多条命令 
#:行注释 
$:变量表达式 
&:在后台执行命令 
*:字符串通配符 
?:单个字符通配符 
二.Bash变量 
1.自定义变量 
用户自定义的变量由字母、数字和下划线组成,并且变量名的第一个字符不能为数字,且变量名大小写敏感。 
varname=value 注意bash不能在等号两侧留空格 
shell语言是非类型的解释型语言,给一个变量赋值实际上就是定义了变量,而且可以赋不同类型的值。引用变量有两种方式,$varname和${varname},为防止变量在字符串中产生歧义建议使用第二种方式,引用未定义的变量其值为空。 
为一个变量赋值一个串,需要用到引号,注意`、’、”的不同,``相当于$() 
为了使变量可以在其它进程中使用,需要将变量导出:export varname 
2.环境变量 
可以用set命令给变量赋值或查看环境变量值,使用unset命令清除变量值,使用export导出变量将可以使其它进程访问到该环境变量。 
3.位置变量 
位置变量对应于命令行参数,其中$0为脚本名称,$1为第一个参数,依次类推,参数超过9个必须使用${}引用变量。shell保留这些变量,不允许用户以另外的方式定义它们,传给脚本或函数的位置变量是局部和只读的,而其余变量为全局的(可以用local关键字声明为局部)。 
4.其它变量 
$?:保存前一个命令的返回码 
$-:在Shell启动或使用set命令时提供选项 
$:当前shell的进程号 
$!:上一个子进程的进程号 
$#:传给脚本或函数的参数个数,即位置变量数减1,不含脚本名称。 
$*:传给脚本或函数的参数组成的单个字符串,即除脚本名称后从第一个参数开始的字符串,每个参数以$IFS分隔(一般内部域分隔符$IFS为1空格)。形同”…” 
$@:传给脚本或函数的参数列表,这些参数被表示为多个字符串。形同”” “” “”…。$*和$@之间的不同方便使用两种方法处理命令行参数,但是在打印时参数外观没有区别。 
如:#vi posparm.sh 
function cutparm 
{echo –e “inside cntparm: $# parms: $*\n”} 
cntparm “$*” 
cntparm “$@” 
#./posparm.sh abc bca cab 
inside cntparm: 1 parms: abc bca cab 
inside cntparm: 3 parms: abc bca cab 
三.Bash操作符 
1.字符串操作符(替换操作符) 
${var:-word} 如果var存在且不为空,返回它的值,否则返回word 
${var:=word} 如果var存在且不为空,返回它的值,否则将word赋给var, 返回它的值 
${var:+word} 如果var存在且不为空,返回word,否则返回空 
${var:?message}如果var存在且不为空,返回它的值, 
否则显示“bash2:$var:$message”,然后退出当前命令或脚本 
${var:offset[]}从offset位置开始返回var的一个长为length的子串, 
若没有length,则默认到var串末尾 
2.模式匹配操作符 
${var#pattern}从var头部开始,删除和pattern匹配的最短模式串,然后返回 剩余串 
${var##pattern}从var头部开始,删除和pattern匹配的最长模式串,然后返回 剩余串,basename path=${path##*/} 
${var%pattern}从var尾部开始,删除和pattern匹配的最短模式串,然后返回 剩余串,dirname path=${path%/*} 
${var%%pattern}从var尾部开始,删除和pattern匹配的最长模式串,然后返回 剩余串 
${var/pattern/string}用string替换var中和pattern匹配的最长模式串 
四.Shell中条件和test命令 
Bash可以使用[ … ]结构或test命令测试复杂条件 
格式:[ expression ]或test expression 
返回一个代码,表明条件为真还是为假,返回0为真,否则为假。 
注:左括号后和右括号前空格是必须的语法要求 
1.文件测试操作符 
-d file file存在并且是一个目录 
-e file file存在 
-f file file存在并且是一个普通文件 
-g file file存在并且是SGID(设置组ID)文件 
-r file 对file有读权限 
-s file file存在并且不为空 
-u file file存在并且是SUID(设置用户ID)文件 
-w file 对file有写权限 
-x file 对file有执行权限,如果是目录则有查找权限 
-O file 拥有file 
-G file 测试是否是file所属组的一个成员 
-L file file为符号链接 
file1 –nt file2file1比file2新 
file1 –ot file2file1比file2旧 
2.字符串操作符 
str1=str2 str1和str2匹配 
str1!=str2 str1和str2不匹配 
str1<str2 str1小于str2 
str1>;str2 str1大于str2 
-n str str的长度大于0(不为空) 
-z str str的长度为0(空串) 
3.整数操作符 
var1 –eq var2var1等于var2 
var1 –ne var2var1不等于var2 
var1 –ge var2var1大于等于var2 
var1 –gt var2var1大于var2 
var1 –le var2var1小于等于var2 
var1 –lt var2var1小于var2 
4.逻辑操作符 
!expr 对expr求反 
expr1 && expr2对expr1与expr2求逻辑与,当expr1为假时不再执行expr2 
expr1 || expr2 对expr1与expr2求逻辑或,当expr1为真时不再执行expr2 
注:另一种逻辑操作符逻辑与expr1 –a expr2 逻辑或expr1 –o expr2 
五.Shell流控制 
1.条件语句:if 
if 条件 IFS=: 
then for dir in $PATH 
语句 do 
[elif 条件 if [ -O dir ]; then 
语句] echo –e “\tYou own $dir” 
[else else 
语句] echo –e “\tYou don’t own $dir” 
fi fi 
2.确定性循环:for done 
for value in list for docfile in /etc/* /usr/etc/* 
do do 
statements using $value cp $docfile ${docfile%.doc}.txt 
done done 
注:for var;…相当于for var in “$@”;… 
3.不确定性循环:while和until 
while 条件 until 条件 
do do 
语句 语句 
done done

count=1 count=1
while [ -n “$*” ] until [ -z “$*” ] 
do do 
echo "parameter $count" echo "parameter $count" 
shift shift 
count='expr $count + 1' count='expr $count + 1' 
done done 
条件为真执行循环体 条件为假执行循环体 
注:整数变量的定义与算法 
declare –i idx 定义整数变量使用$(())无需定义 
idx=1 
while [ $idx!=150 ] 
do 
cp somefile somefile.$idx 
idx=$idx+1 整数算法idx=$(( $idx+1 )) 
done 
另一种算法echo $(( 100/3 ))将加减乘除表达式放入$(())中 
4.选择结构:case和select 
case 表达式 in 表达式和模式依次比较,执行第一个匹配的模式 
模式1) ;;使程序控制流跳到esac后执行,相当于break 
语句;; 允许表达式和含有通配符的模式进行匹配 
模式2) 
语句;; 
…… 
[*) 
语句] 
esac 

select value [ in list ] 按list列表自动生成菜单 
do 若没有list则默认为位置变量 
statements using $value 
done
如:IFS=: 设置域分隔符为:号 
PS3=”choice>;” 改变select默认提示符 
clear 
select dir in $PATH 
do 
if [ $dir ]; then 
cnt=$(ls –Al $dir | wc -l) 
echo “$cnt files in $dir” 
else 
echo “No such choice !” 
fi 
echo –e “\npress ENTER to continue, CTRL-C to quit” 
read 使程序按回车继续,ctrl+c退出 
clear 
done 
5.命令shift 
将存放在位置变量中的命令行参数依次向左传递 
shift n 命令行参数向左传递n个串 
六.Shell函数 
定义:function fname fname () 
{ { 
commands commands 
} } 
调用:fname [ parm1 parm2 parm3 ... ] 
说明:函数在使用前定义,两种定义功能相同 
函数名和调用函数参数成为函数的位置变量 
函数中的变量应该使用local声明为局部变量 
七.输入输出 
限于篇幅,这里不讨论所有输入输出操作符和功能 
1.I/O重定向 
<:输入重定向 
>;:输出重定向(没有文件则创建,有则覆盖) 
>;>;:输出重定向(没有则创建,有则追加到文件尾部) 
<<:输入重定向(here文档) 
格式:command << label 
input… 
label 
说明:使一个命令的输入为一段shell脚本(input…),直到标号(label)结束 
如:cat < $HOME/.profile >; out 
echo “add to file end !” >;>; $HOME/.profile 
ftp:USER=anonymous 
PASS=YC@163.com 
ftp –i –n << END -i:非交互模式-n:关闭自动登录 
open ftp.163.com 
user $USER $PASS 
cd /pub 
close 
END END标记输入结束 
2.字符串I/O操作 
字符串输出:echo 
命令选项:-e:启动转义序列 -n:取消输出后换行 
转义序列:\a:Alt/Ctrl+G(bell)\b:退格Backspace/Ctrl+H 
\c:取消输出后换行\f:Formfeed/Ctrl+J 
\r:Return/Ctrl+M \v:Vertical tab 
\n:八进制ASCII字符\\:单个\字符 \t:Tab制表符 
字符串输入:read 
可以用于用户交互输入,也可以用来一次处理文本文件中的一行 
命令选项:-a:将值读入数组,数组下标从0开始 
-e:使用GNU的readline库进行读入,允许bash的编辑功能 
-p:在执行读入前打印提示 
如:IFS=: 
read –p “start read from file . filename is : \c” filename 
while read name pass uid gid gecos home shell < filename 
do 
echo –e “name : $name\npass : $pass\n” 
done 
说明:如果行的域数大于变量表的变量数,则后面的域全部追加给最后的变量 
八.命令行处理 
命令行处理命令:getopts 
有两个参数,第一个为字母和冒号组成的选项列表字符串,第二个为一个变量名 
选项列表字符串以冒号开头的选项字母排列组成,如果一选项需要一个参数则该选项字母后跟一个冒号 
getopts分解第一参数,依次将选项摘取出来赋给第二个参数变量 
如果某选项有参数,则读取参数到内置变量OPTARG中 
内置变量OPTIND保存着将被处理的命令行参数(位置参数)的数值 
选项列表处理完毕getopts返回1,否则返回0 
如:while getopts “:xy:z:” opt 
do 
case $opt in 
x)xopt=’-xset’;; 
y)yopt=”-yset and called with $OPTARG”;; 
z)zopt=”-zset and called with $OPTARG”;; 
\?)echo ‘USAGE: getopts.sh [-x] [-y arg] [-z arg] file…’ 
exit 1 
esac 
done 
shift ($OPTING-1) 将处理过的命令行参数移去 
echo ${xopt: -‘did not use –x‘} 
echo ${yopt: -‘did not use –y‘} 
echo ${zopt: -‘did not use –z‘} 

echo “Remaining command-line arguments are :” 
for f in “$@” 
do 
echo –e “\t$f\n” 
done 
九.进程和作业控制 
信号处理命令:trap 
格式:trapcommand sig1sig2… 
trap可以识别30多种信号,如中断(Ctrl+c)、挂起(Ctrl+z)等,可以使用kill -l查看信号清单 
当脚本接受到信号sig1、sig2等,trap就执行命令command,command完成后脚本重新执行 
信号可以通过名称或数字来标识 
作业控制命令:bg、fg 
bg:显示后台进程,即用Ctrl+z挂起或‘命令 &’执行的进程 
fg:将后台进程转到前台执行 
kill –9 %n:杀掉第n个后台进程 
附录: 
一.Bash支持的命令行参数 
-a 将所有变量输出  
  -c "string"从string中读取命令  
  -e 使用非交互式模式  
  -f 禁止shell文件名产生  
  -h 定义  
  -i 交互式模式  
  -k 为命令的执行设置选项  
  -n 读取命令但不执行  
  -r 受限模式  
  -s 命令从标准输入读取  
  -t 执行一命令,然后退出shell  
  -u 在替换时,使用未设置的变量将会出错  
  -v 显示shell的输入行  
  -x 跟踪模式,显示执行的命令 
许多模式可以组合起来用,使用set可以设置或取消shell的选项来改变shell环境。打开选项用"-",关闭选项用"+",若显示Shell中已经设置的选项,执行: $echo $- 
二..profile中shell的环境变量意思如下:  
CDPATH 执行cd命令时使用的搜索路径  
HOME 用户的home目录  
IFS 内部的域分割符,一般为空格符、制表符、或换行符  
MAIL 指定特定文件(信箱)的路径,有UNIX邮件系统使用  
PATH 寻找命令的搜索路径(同dos的config.sys的 path)  
PS1 主命令提示符,默认是"$"  
PS2 从命令提示符,默认是">;"  
TERM 使用终端类型

posted @ 2009-12-31 18:52  3qfly  阅读(322)  评论(0编辑  收藏  举报