转载自 Shell编程(/bin/sh和/bin/bash)
查看ubuntu支持的Shell:
$ cat / etc / shells
查看当前shell:
$ echo $SHELL
以下是sh Shell脚本编程,也适用于bash,差异之处已说明。
保留字符及其含义
$ shell变量名的开始,如$var
| 管道,将标准输出转到下一个命令的标准输入
# 注释开始
& 在后台执行一个进程
? 匹配一个字符
* 匹配0到多个字符(与DOS不同,可在文件名中间使用,并且含.)
$- 使用set及执行时传递给shell的标志位
$! 最后一个子进程的进程号
$# 传递给shell script的参数个数
$* 传递给shell script的参数
$@ 所有参数,个别的用双引号括起来
$? 上一个命令的返回代码
$0 当前shell的名字
$n (n:1-) 位置参数
$$ 进程标识号(Process Identifier Number, PID)
>file 输出重定向
`command` 命令替换,如 filename=`basename /usr/local/bin/tcsh`
>>fiile 输出重定向,append
其他:
$$dir
ls > filelist
ls >> filelist
wc -l < filelist
wc -l filelist
sleep 5; echo 5 seconds reaches; ls -l
ps ax |egrep inetd
find / -name core -exec rm {} \; &
filename=`date "+%Y%m%d"`.log
shell变量
Shell有如下四种变量:
.用户自定义变量
.位置变量即 shell script之参数
.预定义变量(特殊变量)
.环境变量
(1)用户自定义变量(数据的存储)
$ COUNT = 1 $ NAME = " He Binwu "$ echo $NAME$ echo ${NAME}
技巧:因为大部分UNIX命令使用小写字符,因此在shell编程中通常使用全大写变量,当然这并不是强制性的,但使用大写字符可以在编程中方便地识别变量。
变量的调用:在变量前加$。
使用unset命令删除变量的赋值。
$ Z = hello $ echo $Zhello $ unset Z $ echo $Z $
在变量未赋值之前其值为空。Bourne Shell允许对变量设置默认值(相当于C#中 ?? 表达式),其格式如下:
${variable:-defaultvalue}
例:
$ echo Hello $UNAME Hello $ echo Hello ${UNAME: - there} Hello there $ echo $UNAME #变量值并未发生变化 there $ UNAME = hbwork $ echo Hello ${UNAME: - there} Hello hbwork
另一种情况:改变变量的值,格式如下:
${variable:=value}
$ echo Hello $UNAME Hello $ echo Hello ${UNAME: = there} Hello there $ echo $UNAME #变量值并未发生变化 there
变量替换中使用命令替换:
echo ${MYDIR} #输出空 echo ${MYDIR: - `pwd`}输出:/ home / pxl / shelltest
在变量已赋值时进行替换:
MYTEST = pxl echo ${MYTEST} echo ${MYTEST: + " changevalue " } echo $MYTEST 输出: pxl changevalue pxl
带有错误检查的有条件变量替换:
echo ${UNAME:? " UNAME has not been set " } echo ${UNAME } #如果上一句判断错误,这里不会执行输出:./test.sh: 17: UNAME: UNAME has not been set
(2)位置变量(Shell参数)
在shell script中位置参数可用$1..$9表示,$0表示内容通常为当前执行程序的文件名。
可以使用shift [n] 来删出指定前n个参数,n默认为1.
脚本 test.sh :shift shift 2 echo $ 1echo $0执行: $ . / test.sh a b c d e 输出: d./test.sh
条件测试命令
(1)数值测试:
-eq :等于则为真。
-ne :不等于则为真。
-gt :大于则为真。
-ge :大于等于则为真。
-lt :小于则为真。
-le :小于等于则为真。
(2)字串测试:
= :等于则为真。
!= :不相等则为真。
-z字串 :字串长度伪则为真。
-n字串 :字串长度不伪则为真。
(3)文件测试:
-e文件名 :如果文件存在则为真。
-r文件名 :如果文件存在且用户有读权限则为真。
-w文件名 :如果文件存在且用户有写权限则为真。
-x文件名 :如果文件存在且用户有可执权限行则为真。
-s文件名 :如果文件存在且至少有一个字符(大小不为零)则为真。
-d文件名 :如果文件存在且为目录则为真。
-f文件名 :如果文件存在且为普通文件则为真。
-c文件名 :如果文件存在且为字符设备文件则为真。
-b文件名 :如果文件存在且为块设备文件则为真。
表达式
(1) 与、或、非
&& :与
|| :或
! : 非(需要有空格)
(2) expr命令
expr命令一般用于整数值,但也可用于字符串。一般格式为:
expr argument operator argument
其中operator为+ - * / %, 但对*的使用要用转义符\。
v1 = 3 v2 = 2 v3 = `expr $v1 \ * $v2` echo $v3输出:6
# 适用于/bin/bash,不适用于/bin/sh v1 = 3 v2 = 2 v3 =$ [v1 * v2] echo $v3
流程控制
(1) if 条件语句
if [ - f " $file " ] ; then newfile = `echo " $file " | sed " s/${OLD}/${NEW}/g " ` if [ - f " $newfile " ]; then echo " ERROR: $newfile exists already " else echo " renaming $file to $newfile ... " mv " $file " " $newfile " fi fi
(2) for 循环
for file in $* ; do if [ -f " $file " ] ; then newfile = `echo " $file " | sed " s/${OLD}/${NEW}/g " ` if [ -f " $newfile " ]; then echo " ERROR: $newfile exists already " else echo " renaming $file to $newfile ... " mv " $file " " $newfile " fi fi done
for n in 9 8 7 6 5 4 3 2 1 ; do if [ -f " $filen.$n " ]; then p = `expr $n + 1 ` echo " mv $filen.$n $filen.$p " mv $filen . $n $filen . $p fi done
# 适用于/bin/bash,不适用于sh for ((i = 1 ;i< = 10 ;i ++ )); do echo $i done
(3) while 循环
while [ - n " $1 " ]; do echo $1 shift done
(4) case 条件
while [ - n " $1 " ]; do case $1 in - h) help;shift 1 ;; # function help is called -f ) opt_f = 1 ;shift 1 ;; # variable opt_f is set - l) opt_l = $2 ;shift 2 ;; # -l takes an argument -> shift by 2 -- ) shift; break ;; # end of options -* ) echo " error: no such option $1. -h for help " ;exit 1 ;; * ) break ;; esac done