0.上节回顾
在上一篇博文中,主要介绍了Shell脚本编程的背景,怎样创建人生中第一个Shell脚本以及Shell变量等内容。接下来将接着介绍介绍Shell编程,主要是围绕着Shell运算、流程控制语句、自定义函数以及脚本调试等方面展开。
1.运算符
1 2 3 4 |
num1=11 num2=22 sum=𝑛𝑢𝑚1+num2 echo $sum |
格式 :expr m + n 或$((m+n)) 注意expr运算符间要有空格
expr命令:对整数型变量进行算术运算 (注意:运算符前后必须要有空格)
1 2 3 4 5 |
expr 3 + 5 expr 3 – 5 echo `expr 10 / 3` 10/3的结果为3,因为是取整 expr 3 \* 10 # \ 是转义符 |
例:计算(2 +3 )×4 的值
-
分步计算
12S=`expr 2 + 3`expr $S \* 4 -
一步完成计算
12345expr `expr 2 + 3` \* 4S=`expr `expr 2 + 3` \* 4`echo $S# 或echo $(((2 + 3) * 4))
$()与${}的区别
$( )的用途和反引号一样,用来表示优先执行的命令
eg:echo $(ls a.txt)
就是取变量了𝑒𝑔:𝑒𝑐ℎ𝑜{PATH}
$((运算内容)) 适用于数值运算
eg: echo $((3+1*4))
2.内置test命令
内置test命令常用操作符号[]表示,将表达式写在[]中,如下:
1 2 3 |
[ expression ] 或者: test expression |
注意:expression首尾都有个空格,和符号[]有空格分割;
eg:
1 |
[ ] ;echo $? |
测试范围:整数、字符串、文件
表达式的结果为真,则test的返回值为0,否则为非0。当表达式的结果为真时,则变量$?的值就为0,否则为非0
2.1.字符串测试
1 2 3 4 5 6 7 8 9 |
test str1 == str2 #测试字符串是否相等 test str1 != str2 #测试字符串是否不相等 test str1 #测试字符串是否不为空,不为空,true,false test -n str1 #测试字符串是否不为空 test -z str1 #测试字符串是否为空 if [ "$1" == "init" ]; then echo "init" fi |
eg:
1 2 3 4 5 6 7 |
name=linzhiling [ “$name” ] && echo ok ; 命令连接符号 && 逻辑与 条件满足,才执行后面的语句 [ -z “$name” ] && echo invalid || echo ok || 逻辑或,条件不满足,才执行后面的语句 test “$name” == ”yangmi” && echo ok || echo invalid |
2.2.整数测试:
1 2 3 4 5 6 |
test int1 -eq int2 测试整数是否相等 equals test int1 -ge int2 测试int1是否>=int2 test int1 -gt int2 测试int1是否>int2 test int1 -le int2 测试int1是否<=int2 test int1 -lt int2 测试int1是否<int2 test int1 -ne int2 测试整数是否不相等 |
eg:
1 2 |
test 100 –gt 100 test 100 –ge 100 |
如下示例两个变量值的大小比较:
-gt表示greater than大于的意思;-le表示less equal表示小于等于。
2.3.文件测试:
1 2 3 4 5 6 7 8 9 |
test -b file 文件存在且是块设备 test -c file 文件存在且是字符型 test -d file 指定文件是否目录 test –e file 文件是否存在 exists test -f file 指定文件是否常规文件 test –L File 文件存在并且是一个符号链接 test -r file 指定文件是否可读 test -w file 指定文件是否可写 test -x file 指定文件是否可执行 |
eg:
1 2 3 4 5 6 |
test -d install.log test –r install.log test –f xx.log ; echo $? [ -L service.soft ] && echo “is a link” test -L /bin/sh ;echo $? [ -f /root ] && echo “yes” || echo “no” |
2.4.多重条件测试:
1 2 3 |
条件1 –a 条件2 逻辑与 两个都成立,则为真 条件1 –o 条件2 逻辑或 只要有一个为真,则为真 ! 条件 逻辑非 取反 |
eg:
1 2 3 4 5 |
num=520 [ -n “𝑛𝑢𝑚”–𝑎“num” –ge 520 ] && echo “marry you” || echo “go on” age=20 pathname=outlog [ ! -d“$ pathname”] && echo usable || echo used |
3.流程控制语句
3.1.if/else命令
- 单分支if条件语句
中括号[]内部和条件判断式用空格隔开;
1 2 3 4 |
if [ 条件判断式 ] then 程序 fi |
或者
1 2 3 |
if [ 条件判断式 ] ; then 程序 fi |
eg:
1 2 3 4 5 |
#!/bin/sh if [ -x /etc/rc.d/init.d/httpd ] then /etc/rc.d/init.d/httpd restart fi |
单分支条件语句需要注意几个点:
if语句使用fi结尾,和一般语言使用大括号结尾不同。
[ 条件判断式 ] 就是使用test命令判断,所以中括号和条件判断式之间必须有空格
then后面跟符号条件之后执行的程序,可以放在[]之后,用“;”分割,也可以换行写入,就不需要";"了。
- 多分支if条件语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
if [ 条件判断式1 ] then 当条件判断式1成立时,执行程序1 elif [ 条件判断式2 ] then 当条件判断式2成立时,执行程序2 ...省略更多条件 else 当所有条件都不成立时,最后执行此程序 fi ``` if [ 条件判断式1 ];then ... elif [ 条件判断式2 ];then ... else ... fi |
示例:
1 |
read -p "please input your name: " NAME |
eg:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#!/bin/bash read -p "please input your name:" NAME #echo $NAME if [ “$NAME” == root ] then echo "hello ${NAME}, welcome !" elif [ $NAME == tom ] then echo "hello ${NAME}, welcome !" else echo "SB, get out here !" fi #print cmake version function cmake_check_update(){ cmake --version > /dev/null if [ $? != 0 ];then echo "no 0" #cmake_update else CMAKE_VERSION=$( cmake --version | awk '{print $3}'|grep -E "([0-9]).([0-9])+.([0-9])+" ); MAJOR_VERSION=$( cmake --version | awk '{print $3}'|grep -Eo "([0-9]+)" | awk 'NR==1 {print $0}' ); MINOR_VERSION=$( cmake --version | awk '{print $3}'|grep -Eo "([0-9]+)" | awk 'NR==2 {print $0}' ); #todo: version >3.13 不动作,小于等于则升级 if [ ${MAJOR_VERSION} -ge 3 ] && [ ${MINOR_VERSION} -ge 13 ];then echo "CMAKE version ${CMAKE_VERSION}" else echo "CMAKE old version ${CMAKE_VERSION}" #cmake_update fi fi } |
3.2.case命令
case命令是一个多分支的if/else命令,case变量的值用来匹配value1,value2,value3等等。匹配到后则执行跟在后面的命令直到遇到双分号为止(;;)case命令以esac作为终止符。
格式
1 2 3 4 5 6 7 8 9 10 11 12 |
CMD=$1 case $CMD in start) echo "starting" ;; Stop) echo "stoping" ;; *) echo "Usage: {start|stop}" ;; esac |
3.3.for循环
for循环命令用来在一个列表条目中执行有限次数的命令。比如,你可能会在一个姓名列表或文件列表中循环执行同个命令。for命令后紧跟一个自定义变量、一个关键字in和一个字符串列表(可以是变量)。第一次执行for循环时,字符串列表中的第一个字符串会赋值给自定义变量,然后执行循环命令,直到遇到done语句;第二次执行for循环时,会右推字符串列表中的第二个字符串给自定义变量,依次类推,直到字符串列表遍历完。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
第一种: for N in 1 2 3 do echo $N done 或 for N in 1 2 3; do echo $N; done 或 for N in {1..3}; do echo $N; done 第二种: for ((i = 0; i <= 5; i++)) do echo "welcome $i times" done 或 for ((i = 0; i <= 5; i++)); do echo "welcome $i times"; done 示例: #查询并添加用户组 for g in group1 group2; do ! getent group $g > /dev/null && addgroup -S $g done |
3.4.while循环
while命令根据紧跟其后的命令(command)来判断是否执行while循环,当command执行后的返回值(exit status)为0时,则执行while循环语句块,直到遇到done语句,然后再返回到while命令,判断command的返回值,当得打返回值为非0时,则终止while循环。
第一种
1 2 3 4 5 |
while expression do command … done |
练习:求1-10 各个数的平方和
第二种:
- 综合使用
根据参数执行不同命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
while [[ $# -ge 1 ]];do case "$1" in "init") echo "init" shift 1 ;; "build") echo "build" shift 1 ;; "help") help shift 1 ;; *) echo "Usage: {init|build}" shift 1 ;; esac done |
3.5.自定义函数
函数代表着一个或一组命令的集合,表示一个功能模块,常用于模块化编程。
以下是关于函数的一些重要说明:
在shell中,函数必须先定义,再调用
使用return value来获取函数的返回值
函数在当前shell中执行,可以使用脚本中的变量。
函数的格式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
函数名() { 命令1….. 命令2…. return 返回值变量 } [ function ] funname [()] { action; [return int;] } function start() / function start / start() |
注意:
如果函数名后没有(),在函数名和{ 之间,必须要有空格以示区分。函数返回值,只能通过$? 系统变量获得,可以显示加:return 返回值,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
4.脚本调试
1 2 3 4 5 6 7 8 9 10 |
sh -x script 这将执行该脚本并显示所有变量的值。 在shell脚本里添加 set -x 对部分脚本调试 sh -n script 不执行脚本只是检查语法的模式,将返回所有语法错误。 sh –v script 执行并显示脚本内容 |
5.shell的字符串和数字的转化(数字自动做字符串处理,变量名做字符串输出用单引号)
shell里面怎么样把字符串转换为数字?
例如:a="024"
1,用${{a}}
2,用let达到(()) 运算效果。
1 2 3 |
let num=0123; echo $num; 83 |
3,双括号运算符:
1 2 |
a=$((1+2)); echo $a; |
等同于:
1 |
a=`expr 1 + 2` |
本文源站链接:https://turbock79.cn/?p=1131
附原文链接
微信赞赏
支付宝赞赏