导读-- 在DOS 中,你可能会从事一些例行的重覆性工作,此时你会将这些重覆性的命令写成批次档,只要执行这个批次档就等於执行这些命令 ......
⒘鞒炭刂?
在介绍流程控制之前,我们先来看看test命令。test命令的参数是条件判断式,当
条件为真时则传回非零值,而条件为伪时则传回零。在所有的流程控制都必须用到
test命令来判断真伪。而test命令的使用方法则列於附录B。
$#@60;eg$#@62;
test $# = 0
如果执行这个程式没有参数时,会传回非零值代表"$# = 0"这个条件成立。反
之则会传回零。
以下介绍各种流程控制:
1. if then
语法以及流程图如下
语法以及流程图如下
│ FALSE
if (condition) <condition>—┐
then │TRUE │
then-commands then-commands │
fi ├————┘
│
condition 是一个test命令。往後所介绍的各种流程中的condition 都是test
命令。
$#@60;eg$#@62;
档名:chkarg
┌———————————┐
│if (test $# != 0) │
│ then │
│ echo Arg1: $1 │
│fi │
└———————————┘
$ chkarg Hello
Arg1: Hello
$ chkarg
$
2. if then else
语法以及流程图如下
│ FALSE
if (condition) <condition>—————┐
then │TRUE │
then-commands then-commands else-commands
else ├————————┘
else-commands │
fi
3. if then elif
语法以及流程图如下
│ FALSE
if (condition1) <condition1>—┐
then │TRUE │ FALSE
commands1 commands1 <condition2>—┐
elif (condition2) │ │TRUE │
then │ commands2 commands3
commands2 ├—————┴————┘
else │
commands3
commands3
fi
$#@60;eg$#@62;
echo word 1: \c
read word1
echo word 2: \c
read word2
echo word 3: \c
read word3
if (test "$word1" = "$word2" -a "$word2"
= "$word3")
then
echo Match: words 1, 2, & 3
elif (test "$word1" = "$word2")
then
echo Match: words 1 & 2
elif (test "$word1" = "$word3")
then
echo Match: words 1 & 3
elif (test "$word2" = "$word3")
then
echo Match: words 2 & 3
else
echo No match
fi
4 or in
语法以及流程图如下
│ FALSE
for var in arg-list ┌—<arg-list还有东西吗?>—┐
do │ │TRUE │
commands │ 从arg-list取得一项 │
done │ 放到变数var │
│ │ │
│ commands │
$#@60;eg$#@62; └——————┘ │
┌———————————┐ ┌———————┘
│for a in xx yy zz │ │
│ do │
│ echo $a │
│done │
└———————————┘
结果如下:
xx
yy
yy
zz
5. for
语法以及流程图如下
│ FALSE
for var ┌—<参数中还有东西吗?>—┐
do │ │TRUE │
commands │ 从参数中取得一项 │
done │ 放到变数var │
│ │ │
│ commands │
$#@60;eg$#@62; └—————┘ │
档名:lstarg ┌———————┘
┌———————————┐ │
│for a │
│ do │
│ echo $a │
│done │
└———————————┘
$lstarg xx yy zz
xx
yy
yy
zz
6. while
语法以及流程图如下
│ FALSE
while (condition) ┌—<condition>—┐
do │ │TRUE │
commands │ commands │
done └————┘ │
┌————┘
│
$#@60;eg$#@62;
┌———————————————┐
│number=0 │
│while (test $number -lt 10) │
│ do │
│ echo "$number\c" │
│ number=`expr $number + 1` │
│done │
│echo │
└———————————————┘
结果如下:
0123456789
7. until
语法以及流程图如下
│ TRUE
until (condition) ┌—<condition>—┐
do │ │FALSE │
commands │ commands │
done └————┘ │
┌————┘
│
它和while 的不同只在於while 是在条件为真时执行回圈,而until 是在条件
为假时执行回圈。
8. break及continue
这两者是用於for, while, until 等回圈控制下。break 会跳至done後方执行
,而continue会跳至done执行,继续执行回圈。
9. case
语法以及流程图如下
│ TRUE
case str in <str=pat1>————commands1—┐
pat1) commands1;; │FALSE TRUE │
pat2) commands2;; <str=pat2>————commands2—┤
pat3) commands3;; │FALSE TRUE │
esac <str=pat3>————commands3—┤
│FALSE │
├————————————┘
│
而pat 除了可以指定一些确定的字串,也可以指定字串的集合,如下
* 任意字串
? 任意字元
[abc] a, b, 或c三字元其中之一
[a-n] 从a到n的任一字元
| 多重选择
$#@60;eg$#@62;
┌———————————————┐
│echo Enter A, B, or C: \c │
│read letter │
│case $letter in │
│ A|a) echo You entered A.;;│
│ B|b) echo You entered B.;;│
│ C|c) echo You entered C.;;│
│ *) echo Not A, B, or C;; │
│esac │
└———————————————┘
10. 函数
格式如下
function-name()
{
commands
}
而要呼叫此函数,就像在命令列下直接下命令一般。
□C Shell
C Shell 有些特性和Bourne Shell一样,但有些不相同。这里介绍与Bourne Shell
不相同的地方。
一、变数
1. 字串变数
这个部分和Bourne Shell的变数一样,只不过在设定变数值时不能使用Bourne
Shell的方式,而必须打:
set var=value
2. 数字运算
基本上C Shell 没有数字变数,但C Shell 却有简单的方法处理数字运算:
@ var operator expression
operator可以是C 语言中的=, +=, -=,......,而expression则是运算式。运
算式的运算子如下:
A. () 改变计算的顺序
~@
B. ~ 位元NOT运算
@~~
! 逻辑否定
C. % 取馀数
C. % 取馀数
/ 除
* 乘
- 减
+ 加
D. $#@62;$#@62; 右移
$#@60;$#@60; 左移
E. $#@62; 大於
$#@60; 小於
$#@62;= 大於等於
$#@60;= 小於等於
!= 不等於
== 等於
F. & 位元AND运算
^ 位元XOR运算
| 位元OR 运算
G. && 逻辑AND
|| 逻辑OR
除此之外,我们也可以检验一个档案的状态,如下
-n filename
而-n可为下列之一
-d 档案是一个目录档案
-e 档案存在
-f 档案为一般的档案
-o 使用者拥有这个档案
-r 使用者可以读取这个档案
-w 使用者可以写入这个档案
-x 使用者可以执行这个档案
-z 档案长度为0
$#@60;eg$#@62;
@ count = count + 1
@ flag = -e /users/cc/mgtsai/mail && -e /usr/spool/mail
3. 阵列
在C Shell 中,我们可以宣告阵列变数,方式如下
set var=(val1 val2 ......)
而var[1]之值为val1,var[2]之值为val2......。而$var代表整个阵列。我们
可以用$#var 来计算阵列个数,也可以用$?var 来检查某个变数是否已宣告。
4. 特殊变数
$argv 和Bourne Shell的$*相似,只不过这是一个阵列。
$argv[n] 和Bourne Shell的$n相同,但不受个数限制。
$#argv 和Bourne Shell的$#相同
$home 和Bourne Shell的$HOME相同
$path 和Bourne Shell的$PATH相似,只不过这是一个阵列
$prompt 和Bourne Shell的$PS1相同
$shell Shell的路径名称
$status 和Bourne Shell的$?相同
$$ 和Bourne Shell的$$相同
$$#@60;
键盘输入
二、执行命令
基本上和Bourne Shell相同,只有一点在Bourne Shell中的"." 命令在C
Shell 中
则为"source"命令。
三、流程控制
在C Shell 中流程控制不像Bourne Shell中一般需要使用test命令。相反地,它和
C 语言类似只要在条件中写出运□式即可。当运算结果不为零时,其值为真,为零
时其值为伪。以下是C Shell的流程控制
1. if
语法如下
if (expression) simple-command
2. goto
语法如下
goto label
这时程式会跳至以l"label:"开头的那一行执行
$#@60;eg$#@62;
if ($#argv == 2) goto goodargs
echo Please use two arguments.
exit
goodrags:
...
3. if then else
这和Bourne Shell的if then, if then else, if then elif 相似。语法如下
A. if (expression) then
commands
endif
B. if (expression) then
commands
else
commands
endif
C. if (expression) then
commands
else if (expression) then
commands
else
commands
endif
4. foreach
这和Bourne Shell的for in相似。语法如下
foreach var (arg-list)
commands
end
5. while
这和Bourne Shell的while相似。语法如下
while (expression)
commands
end
6. break及continue
这和Bourne Shell的break 及continue相似,是用来中断foreach 及while 回
圈。
7. switch
这和Bourne Shell的case相似。语法如下
switch (string)
case pat1:
commands1
breaksw
case pat2:
commands2
breaksw
case pat3:
commands3
breaksw
endsw
□附录A expr命令
命令格式
expr expression
叙述
expression是由字串以及运算子所组成,每个字串或是运算子之间必须用空白隔开
。下表是运算子的种类及功能,而优先顺序则以先後次序排列,我们可以利用小括
号来改变运算的优先次序。其运算结果则输出至标准输出上。
: 字串比较。比较的方式是以两字串的第一个字母开始,而以第二个字串的
字母结束。如果相同时,则输出第二个字串的字母个数,如果不同时则传
回0 。
* 乘法
/ 除法
% 取馀数
+ 加法
- 减法
$#@60; 小於
$#@60;= 小於等於
= 等於
!= 不等於
$#@62;= 大於等於
$#@62; 大於
& AND运算
| OR运算
当expression中含有"*", "(", ")"
等符号时,必须在其前面加上"\" ,以免被
Shell 解释成其它意义。
$#@60;eg$#@62; expr 2 \* \( 3 + 4 \) 其输出为14
□附录B test命令
命令格式
test expression
叙述
expression中包含一个以上的判断准则以作为test评诂的标准。两准则间用"-a"代
表逻辑AND 运算,"-o"代表逻辑OR运算,而在准则前放置一"!" 代表NOT
运算。如
果没有括号,则优先权则为"!" $#@62; "-a" $#@62; "-o"
。和expr命令相同,相使用左右括
号时,必须在其前面加上"\" 。以下是有关准则的叙述(合叙述时传回真,否则传
回伪):
string string不为空白字串
-n string string的长度大於0
-z string string的长度等於0
string1=string2 string1等於string2
string1!=string2 string1不等於string2
int1 -gt int2 int1大於int2
int1 -ge int2 int1大於等於int2
int1 -eq int2 int1等於int2
int1 -ne int2 int1不等於int2
int1 -le int2 int1小於等於int2
int1 -lt int2 int1小於int2
-r filename 档案可读取
-w filename 档案可写入
-x filename 档案可执行
-f filename 档案为一般档
-d filename 档案为目录
-s filename 档案为非空的一般档
$#@60;eg$#@62; test -r "$filename" -a -s "$filename"