shell脚本语句
运算符符
-
运算符的使用+ - * /
1. expr是计算整数类型行的数据
2. 运算符左右都要有空格
3. ``和$()是取结果集4. 注意*必须要通过\转义,不然会出错 5. ``与$()不但可以取整数运算的结果,还可以取shell命令的结果集,比如:result= `ls`或者$(ls) 6. result='expr num1 % num2'=num1/num2商...余数 ``` num=1 num1=2 num2=`expr $num + $num1` //num2=`expr $num \* $num1` echo "${num2}" ``` 7. 可以用$((num1+num2))
-
let关键字
num1=1 num2=2 let num3=num1+num2 echo "${num3}"
- 可以用在 + - * / % ++ --
- ++ --(都只能用在let里,不能在expr里使用)
- 后缀++
num1=1 let num2=num1++ printf "num1=%s\n" "${num1}" printf "num2=%s\n" "${num2}"//num2=1,num=2
- 前缀++
num1=1 let num2=++num1 printf "num1=%s\n" "${num1}" printf "num2=%s\n" "${num2}"//num2=2,num=2
- 后缀--
num1=1 let num2=num-- printf "num1=%s\n" "${num1}" printf "num2=%s\n" "${num2}"//num2=1,num=0
- 前缀 --
num1=1 let num2=--num printf "num1=%s\n" "${num1}" printf "num2=%s\n" "${num2}"//num2=0,num=0
- +=
num1=1 let num2+=num1 printf "num2=%s\n" "${num2}"//num2=3
3 . 整数之间的关系运算符
- \ > \ < \ >= \ <= != ==
- -gt -ge -lt -le -eq -nq
- 在关系运算符中,运算结果是一个逻辑,如果关系表达式成立,逻辑值为1,否则为0。
- 除!=,==都要用\转义
- !=可以用\转义也可以不用\转义
- \ =,=,==,==(由编译器决定,mac支持=,=)
num1=1 num2=2 num3=`expr $num1 \> $num2` echo "${num3}"
关系运算符语句
-
if语句:如果一个数大于5,然后输出这个数,否则如果这个数小于5,然后说明这个数小于5
if [] then 语句体 elif then 语句体 else 语句体 fi 注意点1. []左右两边都要有空格 2. 关系运算符用-gt 等表示
printf "请输入一个数:" read num if [ $num -gt 5 ] then echo "${num}" elif [ $num -lt 5 ] then printf "%s小于5\n" "${num}" else printf "这个数等于5" fi
- 总结:
- else可以没有,如果有else,必须放在最后面,else下面没有then
- elif可以没有,必须要放在if与else中间的位置
- if语句只能执行一个分支
- if结束的标志fi
//输入两个整数求最大值输出
printf "请输入两个整数\n" read num1 read num2 if [ $num1 -gt $num2 ] then printf "最大值为%s\n" "${num1}" else printf "最大值为%s\n" "${num2}" fi
- 总结:
-
字符串运算符
- =:判断字符串是否相等
- !=:判断字符串是否不等
string1="hello" string2="hello" if [ $string1 == $string2 ] then echo "equal" else echo "not equal" fi
- -z:zero:判断字符串是否为空或是不存在
string="" if [ -z $string ] then echo "字符串为空" else echo "字符串不为空" fi
-
文件运算符
- -d:判断是否为目录文件
- -f:判断是否为普通文件
- -r: 判断是否可读
- -w:判断是否可写
- -x:判断是否可执行
- -e:exsit:判断是否存在
//练习:判断~/share是否存在,如果不存在就创建这个文件,如果存在就提示已存在的信息。
-
case语句
case 变量 in 条件1) 语句体1 ;; 条件2) 语句体2 ;; esac
printf "请输入一个数\n" read num case $num in 1) printf "是1" "${num}" ;; 2) printf "是2" "${num}" ;; *) printf "啥都不是" ;; esac
- 注意点
- 结束标志必须是esac
- 值1)和值2)可以相同
- 如果值1)和值2)都不满足,就会来到*)
- *)可以不写,但要写就要写在最后
- 每一个分支结束都有一个;;
-
数组
- 数组的初始化
- 一个变量一个变量进行初始化
- array1[0]=8
- array1[1]=9
- 一个一个变量进行初始化,可以间隔赋值,还可以不从位置0开始。比如aray1[1]=2,array1[5]=5
- 集体赋值
- array=(1 2 3 4 hello)(可以是不同数据类型)
- 一个变量一个变量进行初始化
- 数组元素的访问
- ${数组名[下标]}
- 遍历数组里所有的元素
- ${数组名[*]||[@]}
a=(1 2 3 4 hello) echo "${a[2]}" echo "${a[@]}"
- 数组的初始化
-
while循环
while [] do 语句体 done
sum=0 i=1 while [ $i -le 100 ] do let sum=sum+i; let i++; done echo "sum=${sum}"
-
参数
- ./XX.sh
- $0:代表执行文件./XX.sh
- $1:代表执行的第一个参数
- $2:代表执行的第二个参数
- $n:代表执行的第二个参数
- $#:代表执行的参数个数,不包括命令本身
- ./XX.sh
-
逻辑运算符
- && 并且:如果事件1成立并且事件2也成立,整个事件才成立。否则不成立。
- || 或者:两个事件只要有一个成立,整个事件就成立。
- ! :对事件取反
案例1 printf "请输入一个数\n" read num #if [ $((num%5)) -eq 0 ] && [ $((num%3)) -eq 0 ] if [[ $((num%5)) -eq 0 && $((num%3)) -eq 0 ]] #if [ $((num%5)) -eq 0 -a $((num%3)) -eq 0 ](用了-a,-o就可以只用一个[]) then echo "YES" else echo "NO" fi
//判断闰年(能被4整除,且不被100整除,且可以被400整除)
案例2 printf "请输入一个年份\n" read num if [[ $((num%4)) == 0 && $((num%100)) != 0 ]] || [ $((num%400)) == 0 ] then printf "是闰年" else printf "不是闰年" fi
-
for循环
- 格式:
for 变量 in 参数列表 do 语句体 done
- 遍历打印当前目录下的子目录与子文件
value=`ls` for file in $value do echo "${file}" done
10.break:是跳出整个循环
- 当碰到break时,直接跳
出循环,break下面的语句不会被执行。
- break只跳出最近的一层循环
//计算和时只要大于54就退出
```
count=0
while [ $count -le 1 ]
do
i=1
sum=0
while [ $i -le 100 ]
do
if [ $sum -gt 54 ]
then
break
fi
let sum+=i
let i++
done
printf "sum=%s\n" "${sum}"
printf "i=%s\n" "${i}"
let count++
done
```
-
continue
- 当碰到continue时,跳出本层循环当前的一次循环,continue下面的语句不会被执行
- continue只能存在于循环中。
//1-20和,跳过3的倍数
i=1 sum=0 while [ $i -le 20 ] do if [ $((i%10)) == 3 ] then let i++ continue fi let sum+=i let i++ done echo "sum=${sum}" 分析:i=3时,if条件成立,执行continue,那么continue下面的语句就不会被执行,继续返回到while判断的语句看条件是否成立,如果成立继续执行
-
死循环
while: do 语句体 done
-
shell函数
- 函数调用之前必须要有相应的函数
- 什么时候用到函数
- 执行的功能类似
- 根据实际需求,需要时就用
- shell函数定义格式
function 函数名() { }
- 调用函数:直接写函数名
- 函数参数传递
function test() { echo "$0" echo "$1" echo "$2" echo "${10}" echo "hello world" } test 1 2 3 4 5 6 7 8 9 100 分析:1. 当参数作为shell函数参数传递时,当在函数里面接受n>=10个参数时,要加上${n} 2. $0不是test,而是shell文件本身 3. 函数里面的$1与外面的与外面的$1不同,但是函数里面的$0与函数外面的$0相同。
- 函数返回值
sum() { num1=$1 num2=$2 let value=num1+num2 return $value } sum 1 2 echo "sun=$?" sum 2 3 echo "sun=$?"//结果为sum=3\nsum=5\n 分析:1. **函数如果是return出来的结果,我们用$?接受,$?是接受最后运行的一次脚本** 2. 如果return后面的值大于255,那么函数运行完后用$?接受,$?=value%256。 3. 怎么接受return出来比255大的值,解决之道:使用echo num 返回出来,函数外使用变量接收,value=`函数名`,从而对value进行操作。
- shell函数里面可以内嵌创建函数
a() { b() { echo "aaa" } } a b b在什么情况下会被使用,先要调用a,因为a里有b的实现
- 条件函数
a() { value=1 if [ $value == 1 ] then b() { echo "aaa" } else c() { echo "ccc" } } a b 函数b和函数c在什么情况下可以调用,先运行函数a,因为a中有函数b和函数c的实现,在if语句条件成立时实现函数b的定义;else其他情况实现函数c的定义。
- 总结:
- function关键字可以不写
- shell函数可以有return,也可以没有
- 如果return出来的结果必须要用$?接收
- 如果是用echo保存的结果集,必须要用value=·test·接收
test()
{
echo 555
}
value=test
echo "test函数返回值为${value}"
//习题:求1-100偶数和
sum=0
i=1
while [ $i -le 100 ]
do
if [ `expr $i % 2` -eq 0 ]
then
let sum=sum+i
fi
let i++
done
echo "sum=${sum}"
//打印99乘法表
i=1
j=1
while [ $i -le 9 ]
do
j=1
while [ $j -le $i ]
do
t=`expr $i \* $j`
printf "%s*%s=%s " "$i" "$j" "$t"
let j++
done
printf "\n"
let i++
done
//输入两个整数,再输入一个+-*/运算符,根据运算符,计算两个数结果,用case
printf "输入两个整数"
read i
read j
printf "输入一个运算符"
read s
case $s in
"+")
printf "%s+%s=%s\n" "${i}" "${j}" "$((i+j))"
;;
"-")
printf "%s-%s=%s\n" "${i}" "${j}" "$((i-j))"
;;
"*")
printf "%s*%s=%s\n" "${i}" "${j}" "$((i*j))"
;;
"/")
printf "%s+%s=%s\n" "${i}" "${j}" "$((i/j))"
;;
esac
//打印
*
***
*****
*******
printf "请输入一个数\n"
read s
i=1
j=1
while [ $i -le $s ]
do
j=1
while [ $j -le $((s-i)) ]
do
printf " "
let j++
done
k=1
while [ $k -le $((2*i-1)) ]
do
printf "*"
let k++
done
printf "\n"
let i++
done
//脚本编写小练习:做一个sh 1.sh
- 判断是否有参数,参数是否为1
- 判断文件是否存在
- 如果存在,判断是否是普通文件
- 如果是普通文件,修改权限
- 运行
- 让这个命令在全局有效
- chmod 777 XX.sh
- mv XX.sh mysh
- sudo cp mysh /bin
- 附加:判断是否为.sh文件是再进行下一步
value="$1"
lengh=${#value}
value1=${value:$((lengh-3)):3}
if [ $# -eq 0 ]
then
echo "what do you want to do?"
elif [ $# -eq 1 ]
then
if [ -e $1 ]
then
if [ -f $1 ]
then
if [ $value1 == ".sh" ]
then
chmod 777 $1
./$1
else
printf "no .sh\n"
fi
else
echo "no such files"
fi
else
echo "no such files or directory"
fi
else
echo "too much arguements"
fi
今日小结
昨天刚接触脚本的时候抱着和其他人一样的感觉走,只是听说过脚本这个名词(游戏脚本现在好像十分流行)却不知道具体实现的功能与作用。用法与熟悉的C语言几乎完全不同,各类操作操碎了我的心。直到下午,亲爱的苍老师叫我们做了一个小练习,自己编写了一个类似sh作用的脚本直接运行.sh文件。让我醍醐灌顶,原来还可以这么用!不过我说的不是脚本的用法,而是苍老师编写程序时思路的用法。原谅我的词穷,这种东西只可意会不可言传。在那种思想的领导下,编写程序时思路比以前升级了1/3,速度比以前提高了1/3,如果将这种思路与方法熟练运用。自己的编程能力应该可以从中了玄冥神掌半死不活的张无忌升级成练了九阳神功第九重。
$小结
- 现在假使有函数
test()
{
value1=$1
value2=$2
}
test year(=$1) mouth(=$2)
输出结果为$?
- 假如现在判断的是执行文件后参数的个数
./XX.sh year mouth
year=$1
mouth=$2