因为Shell主要是字符串处理语言,因此利用Shell变量对字符串作不少事。然而,由于算术运算也是必要的,因此POSIX Shell也提供利用Shell变量执行算术运算的机制。java
export与readonly函数
export用于修改或打印环境变量,readonly则使得变量不得修改。测试
因为许多商用UNIX系统里的/bin/sh,仍然不是POSIX兼容版本。所以,export与readonly的变量赋值形式可能没法工做。要实现严格的可移植性,可以使用:命令行
FOO=somevalue排序
export FOO字符串
BAR=anothervalue字符串处理
readonly BARstring
export命令最多见的用法出如今设置环境变量中:it
PATH=$PATH:/usr/local/bin 更新PATHio
export PATH 导出
export命令可用于显示当前环境:
$ export -p
删除环境变量:
env -i PATH=$PATH HOME=$HOME LC_ALL=C awk '...' file1 file2
unset命令从执行中的Shell中删除变量与函数:
unset full_name 删除full_name变量
unset -v first middle last 删除其余变量
unset -f删除函数:
who_is_on() { 定义函数
who | awk '{ print $1 }' | sort -u 产生排序后的用户列表
}
unset -f who_is_on 删除函数
位置参数:
因为历史缘由,当整数大于9时,就应该以花括号({})括起来:
echo first arg is $1
echo tenth arg is ${10}
特殊变量$#,$*,$@,"$*","$@"
shift命令是用来截取来自列表的位置参数,从左开始。一旦执行shift,$1的初始值会永远消失,取而代之的是$2的旧值。$#值则会逐次减1.
$ set -- hello "hi there" greetings
$ echo there are $# total arguments
there are 3 total arguments
[root@bsg-1 dict]# for i in $*
> do echo i is $i
> done
i is hello
i is hi
i is there
i is greetings
[root@bsg-1 dict]# for i in $@
> do echo i is $i
> done
i is hello
i is hi
i is there
i is greetings
[root@bsg-1 dict]# for i in "$*"
> do echo i is $i
> done
i is hello hi there greetings
[root@bsg-1 dict]# for i in "$@"
> do echo i is $i
> done
i is hello
i is hi there
i is greetings
[root@bsg-1 dict]# shift
[root@bsg-1 dict]# echo there are now $# arguments
there are now 2 arguments
[root@bsg-1 dict]# for i in "$@"
> do echo i is $i
> done
i is hi there
i is greetings
if...then...elif...then...else...fi:
固然 &&、||也有若是...就/不...
好比 some_command && { one command a second command and a third command }
只有在some_command成功时他们才被执行。使用if可让它更为简洁:
if some_command
then
one command
a second command
and a third command
fi
test命令:用来测试文件属性、比较字符串以及比较数字
case语句:能够类比java或C中的switch...case
case $1 in
-f)
...
;;
-d | --directory)
...
;;
*)
echo $1: unknown option > $2
exit 1
# 在"esac"以前的;;形式是一个号习惯,不过并不是必要
esac
虽然你可能会以为在每一个模式列表以后的不对称的右圆括号有点奇怪,不过这也是Shell语言里不对称
定界符的惟一实例
*模式是传统用法,但非必须,它是做为一个默认的状况。
循环:for循环里的in列表(list)是可选的,若是省略,Shell循环会遍历整个命令行参数。
这就好像你已经输入了for i in "$@":
for i # 循环经过命令行参数
do
case $i in
-f)
...
;;
...
esac
done
while与until
while与until惟一的不一样之处在于,如何对待condition的退出状态。只要condition是成功退出,while会继续循环。只要condition未成功结束,until则执行循环
例如:
pattern=... 模式会控制字符串的缩减
while [ -n "$string" ] 当字符串不是空时
do
处理$string的当前值
string=${string%$pattern} 截去部分字符串
done
break与continue:这个从C借用来的,这里再也不细说
最后要重点讲下的是函数
函数是指一段单独的程序代码,用以执行一些定义完整的单项工做,
函数在使用以前必须先定义。
[root@bsg-1 ~]# wait_for_user() {
> until who | grep "$1" > /dev/null
> do
> sleep $(2:-30)
> done
> }
[root@bsg-1 ~]# wait_for_user root
[root@bsg-1 ~]# wait_for_user root 60
在函数体中,位置参数($1,$2,...,$#,$*,以及$@)都是函数的参数,父脚本的参数则临时地被函数参数所掩盖或隐藏。
在Shell函数里,return命令的功能与工做方式都与exit相同:
answer_the_question() {
...
return 42
}
好了,这一节就到这儿,下一节讲下I/O及文件与命令执行!