算数运算
expr数值运算工具
实例如下:(dd的值是aa和bb的和)
表达式求值:
加减乘除
算数运算一共有四种形式:形式如下
let C=$A+$B
C=$[$A+$B]
C=$(($A+$B)) 这是证书运算
C=`expr $A + $B` (反引号,表达式和运算符之间要有空格)
运行方式差异(source, shscript, ./script)
这里新建了一个filename.sh脚本
(注:read -p "........." XXXX 先提示一个.....信息,然后输入XXX内容。)
我们已知脚本不存在问题。我们echo一下两个变量,发现不存在。
发现无该变量。这是因为子进程的关系。我们写的脚本相当于一个子进程,而echo变量的时候是在父进程
这时,我们子进程中的变量便无法在父进程中显示。
如何解决呢?我们需要用到source,如截图所示,外面也可以显示变量了
shell中的判断式及控制流程
变量表达式
条件判断命令test
条件测试类型
整数测试
test n1 -参数 n2 真返回0,假返回1
参数如下:
-lt 小于 little
-le 小于等于 little equal
-gt 大于 great
-ge 大于等于 great equal
-eq 等于 equal
-ne 不等于 not equal
栗子:
注:test语句的等价形式[ 1 -lt 4 ] 表达式和中括号之间有空格
栗子:如果输入一个参数x是正数,那么显示x number is positive
文件测试
参数:
-f 存在且是普通文件
-d 存在且是目录
-s 存在且字节数大于0
-r 存在且可读
-w 存在且可写
-x 存在且可执行
test -d "mydoc" 判断mydoc是否是目录
栗子: 检测从命令行输入的文件是否存在
分析:当 sh eg2.sh时,不存在参数。所以执行第一个if语句(即判断参数个数是否是1)
当,后面接上参数的时候,执行第二个if,判断是否存在且是普通文件。
字符串测试
test s 字符串s非空
test s1 = s2 字符串s1等于s2
test s1 != s2 字符串s1不等于s2
test -z s 字符串长=0,就是空串 zero
test -n 字符串长>0
-a逻辑与
-o逻辑或
!逻辑非
控制流程 (分支、循环流程)
seq命令:产生1-9的数字序列
分支结构
if 分支
if [ $# -eq 0 ]
then
echo “输入了0个参数”
elif[ $# -gt 1 ]
then echo “输入了多个参数”
else echo “输入了1个参数”
case
case “$#” in
0)echo “输入了0个参数”;;
1)echo “输入了1个参数”;;
*)echo “输入了多个参数”;;
esac
每个分支条件后必须以两个分号结尾
循环结构
for循环
for i in `seq 1 9`
do
echo `expr $i \* 10`
done
或写echo $(expr $i \* 10)
read 变量1 [变量2 。。。]
可以从键盘上读取多个变量的值,用户输入数据时,以空格或者Tab键作为分隔。
如果输入的数据个数不够,则从左到右对应赋值,没有输入的变量为空;
如果输入的数据个数超了,则从左到右对应赋值,最后一个变量被赋予剩余的所有数据。
-p:指定读取值时的提示符;
read–p “please intput a num:”num
栗子:
输出a到b序列数各数的10倍数
read a b
for i in `seq $a $b`
do
echo $(expr $i \* 10)
while循环
使用while和break,等待用户登陆
Break和continue命令
Break就是跳出循环不执行 continue是跳出本次循环
while condition1 #外部循环
do ...
while condition2 #内部循环
do ...
break 2 #外部循环的中断 这里是全部跳出循环
done
done
... #在中断之后,继续执行这里的程序
栗子:
shell中的函数
定义函数
hello()
{
echo "Hello there today's date is `date`“
}
所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。上面的例子中,函数名为h ello,函数体包含一个echo语句,反馈当天日期。
在脚本中使用函数
#!/bin/sh
# func1.sh
hello ()
{
echo "Hello there today's date is `date`“
}
echo "now going to the function hello”
hello
echo “back from the function"
上面例子中,函数定义于脚本顶部。可以在脚本中使用函数名hello调用它。函数执行后,控制返回函数调用的下一条语句,即反馈语句back from the function。
参数可以传递给函数,并由脚本进行访问
fname arg1 arg2
fname()
{
echo $1,$2;
echo "$@";
echo "$*"
return 0;
}
数组
数组定义
可以在单行中使用一列值来定义一个数组:
array_var= (1 2 3 4 5 6)
#这些值将会存储在以0为起始索引的连续位置上
另外,还可以将数组定义成一组“索引-值”:
array_var[0]="test1"
array_var[1]="test2"
array_var[2]="test3"
array_var[3]="test4"
array_var[4]="test5"
关联数组
关联数组的下标和值称为键值对,它们是一一对应的关系。在关联数组中,键是唯一的,值可以不唯一。
定义关联数组
shell 的关联数组和shell 的下标数组在定义和使用上完全一样,只是在索引上有区别。
需要注意的是,在使用关联数组之前,需要使用命令declare -A array 进行显示声明
栗子:
name=(jim tom lucy)
declare -A phone #关联数组的声明,此时phone就是一个关联数组phone=([jim]=135 [tom]=136 [lucy]=158)
for iin `evalecho {0..$((${#name[*]}-1))}` #生成一个序列,0到name数组长度-1
do
echo ${name[i]} phone number is ${phone["${name[i]}"]}
done
语法描述
${!array[*]} 取关联数组所有键
${!array[@]} 取关联数组所有键
${array[*]} 取关联数组所有值
${array[@]} 取关联数组所有值
${#array[*]} 关联数组的长度
${#array[@]} 关联数组的长度