shell编程入门(二)
while循环
#! /bin/bash
i=0
while [ ${i} -lt 6 ]
do
echo ${i}
let i++
done
结果
ZHR:md zc$ ./test.sh
0
1
2
3
4
5
死循环
while就很适合来做死循环,至于死循环可以用来做什么,我们可以想象这么一个场景:要求用户输入,只有输入了正确或者说是符合标准的答案才可以,这个时候我们就需要死循环来确定“只有”的情况。
#! /bin/bash
while :
do
echo "我在循环"
done
注意: while后面是有一个空格的,而且空格后有英文的 :
或者
#! /bin/bash
while true
do
echo "我在循环"
done
结果就不亮出来了,因为满屏的都是“我在循环”
case … esac 选择
就很像java的switch-case选择,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case … esac 语句,esac(就是 case 反过来)作为结束标记。
如果匹配出结果后就不再执行匹配
可以匹配字符串和数字
匹配数字
#! /bin/bash
a=11
case ${a} in
1) echo "我是1"
;;
11) echo "我是11"
;;
esac
结果
ZHR:md zc$ ./test.sh
我是11
匹配字符串
#! /bin/bash
a=zhangsan
case ${a} in
zhangsan) echo "我是zhangsan"
;;
lisi) echo "我是lisi"
;;
esac
结果
ZHR:md zc$ ./test.sh
我是zhangsan
都不匹配的保底选择*
#! /bin/bash
a=zhangsan
case ${a} in
wangwu) echo "我是zhangsan"
;;
lisi) echo "我是lisi"
;;
zhaoliu) echo "我是zhaoliu"
;;
*) echo "我是谁我在哪儿"
;;
esac
结果
ZHR:md zc$ ./test.sh
我是谁我在哪儿
跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。
break
break命令允许跳出所有循环(终止执行后面的所有循环)。
#! /bin/bash
while true
do
echo "请输入数字1-5"
read YAML
case ${YAML} in
1|2|3|4|5) echo "你输入的是${YAML}"
;;
*) echo "你输入的不是1-5的数字,游戏结束"
break
;;
esac
done
结果
ZHR:md zc$ ./test.sh
请输入数字1-5
2
你输入的是2
请输入数字1-5
6
你输入的不是1-5的数字,游戏结束
或者
#! /bin/bash
sum=0
for i in 1 2 3 4 5 6 7
do
if [ ${i} -eq 4 ];then
break
fi
((sum+=i))
done
echo ${sum}
结果
ZHR:md zc$ ./test.sh
6
continue
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
一般和if搭配使用
#! /bin/bash
sum=0
for i in 1 2 3 4 5 6 7
do
if [ ${i} -eq 4 ];then
continue
fi
((sum+=i))
done
echo ${sum}
结果
ZHR:md zc$ ./test.sh
24
EOF
在shell编程中,遇大段文本或代码时,经常会用到eof,通常与<<一起使用,表示后续的输入作为子命令或子Shell的输入,直到遇到EOF为止,再返回到主Shell。比如说,我要进入不同的数据库,或者说要ssh不同的主机,然后在对应的主机上输入各种各样的指令,可以大概理解为从控制台A跳转到了新的控制台B,在控制台B中的操作就可以放到EOF中,甚至你有一个ssh跳转主机的列表,里可以for循环它,然后把EOF放到do-done里不是很妙哉。
EOF只是一个分界符,当然也可以用abcde替换。
当shell遇到<<时,它知道下一个词是一个分界符。在该分界符以后的内容都被当作输入,直到shell又看到该分界符(位于单独的一行)。
此分界符可以是所定义的任何字符串,其实,不一定要用EOF,只要是“内容段”中没有出现的字符串,都可以用来替代EOF,完全可以换成abcde之类的字符串,只是一个起始和结束的标志罢了。
最方便的演示办法就是拿adb shell了。
#! /bin/bash
adb shell<<EOF
cd /sdcard/images;
touch zzz1.txt;
EOF
结果
ZHR:md zc$ adb shell
HWVCE:/ $ cd sdcard/images/
HWVCE:/sdcard/images $ ls
20200312110902.jpg 20200312110914.jpg abcd.jpg zhangyin111.txt zzz.txt
函数
1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。
function fun()=fun()
#! /bin/bash
add(){
echo "hello"
}
add
和
#! /bin/bash
function add(){
echo "hello"
}
add
的结果是一样的。
ZHR:md zc$ ./test.sh
hello
函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
这一点和java或者python等语言完全不一样,不能在定义函数的时候就定义入参。
#! /bin/bash
add(){
echo "第一个输入的数字为:$1"
echo "第二个输入的数字为:${2}"
echo "第十个输入的数字为:${10}"
echo "第十个输入的数字为:$10"
echo "第十个输入的数字为:${11}"
echo "总共输入了$#个数字"
echo "遍历一下输入的数字:$*"
}
add 1 2 3 4 5 6 7 8 9 10 11 12 13
结果
ZHR:md zc$ ./test.sh
第一个输入的数字为:1
第二个输入的数字为:2
第十个输入的数字为:10
第十个输入的数字为:10
第十个输入的数字为:11
总共输入了13个数字
遍历一下输入的数字:1 2 3 4 5 6 7 8 9 10 11 12 13
but : 其实我们最好还是用${1}这样的表达式来获取参数,至于为什么,需要你手动写一下就明白了。
$# 传递到脚本或函数的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
带retuen
#! /bin/bash
add(){
echo "第一个输入的数字为:$1"
echo "第二个输入的数字为:${2}"
echo "第十个输入的数字为:${10}"
echo "第十个输入的数字为:$10"
echo "第十个输入的数字为:${11}"
echo "总共输入了$#个数字"
echo "遍历一下输入的数字:$*"
return $((${1}+${11}))
}
add 1 2 3 4 5 6 7 8 9 10 11 12 13
echo "第1个和第11个数字的和为:$?"
结果
ZHR:md zc$ ./test.sh
第一个输入的数字为:1
第二个输入的数字为:2
第十个输入的数字为:10
第十个输入的数字为:10
第十个输入的数字为:11
总共输入了13个数字
遍历一下输入的数字:1 2 3 4 5 6 7 8 9 10 11 12 13
第1个和第11个数字的和为:12
函数返回值在调用该函数后通过 $? 来获得。
$(())
在刚才的return中我们用到了$(()):它是用来作整数运算的。
$(( )) 的整数运算符号大致有这些:+ - * / :分别为 “加、减、乘、除”。
#! /bin/bash
a=11
b=22
echo $((${a}+${b}))
其实, ( ( ) ) 中 的 参 数 也 可 以 不 用 (())中的参数也可以不用 (())中的参数也可以不用,就像下面这样,但是出于统一,我们还是加上吧
#! /bin/bash
a=11
b=22
echo $((a+b))
结果
ZHR:md zc$ ./test.sh
33