【shell编程】

case…in分支语句

case…in分支语句的格式
1. 格式
	case $变量名  in        <====> switch ... case
		常量表达式1)        <====> case 常量表达式:
			shell语句		 <====> C语句
			;;             <====> break;  在shell中两个分号不可以省略
		常量表达式2)
			shell语句
			;;
		常量表达式3)
			shell语句
			;;
		
		......
		
		*)					<====> default:   使用的是*通配符
			shell语句
			;;
	esac

2. 常量表达式的书写格式
	1> a)   ----> 表示字符a
	2> 2)   ----> 表示数字2
	3> a|b|c|d)  ----> 表示a,d,c,d中的任意一个
	4> [a-zA-Z])  ----> 表示,a-z和A-Z的任意一个
	5> Y|y|yes|YES|Yes)  ---> 表示Y|y|yes|YES|Yes字符串中的任意一个
	6> [1-9]) ---> 数字1-9中的任意一个。
	
	在case...in分支语句中,除了最后一个分支的两个分号可以省略,
	其他分支的两个分号都不可以省略
case…in的练习题

1. 从终端输入一个字符,判断字符是数字,还是字符,还是标点符号。

#!/bin/bash
# your code

read -p "请输入一个字符 > " ch

case $ch in 
    [0-9])
        echo "$ch 是一个数字"
        ;;
    [a-zA-Z])
        echo "$ch 是一个字母"
        ;;
    \,|\.|\;|\?|\!)
        echo "$ch 是一个标点符号"
        ;;
    *)
        echo "$ch 既不是数字,也不是字母,也不是标点符号"
        ;;
esac

2. 从终端输入成绩,判断成绩的等级,A,B,C,D,E。

#!/bin/bash
# your code
read -p "请输入你的成绩 > " score

if [ $score -lt 0 -o $score -gt 100 ]
then
    echo "输入成绩不合理请重新输入"
    exit
fi

level=$((score / 10))
case $level in
    10|9)
        echo "$score 成绩评定为 A"
        ;;
    8)
        echo "$score 成绩评定为 B"
        ;;
    7)
        echo "$score 成绩评定为 C"
        ;;
    6)
        echo "$score 成绩评定为 D"
        ;;
    *)
        echo "$score 成绩评定为 E"
        ;;
esac

3. 从终端输入年和月,判断是闰年还是平年,以及月份对应的天数。

#!/bin/bash
# your code

read -p "请输入年和月 > " year mouth

if [ $year -lt 0 ] ; then 
    echo "$year 不合理请重新输入"
    exit
fi

if [ $mouth -lt 1 ] || [ $mouth -gt 12 ] ; then 
    echo "输入的月份不合理,请重新输入"
    exit
fi

case $mouth in 
    1|3|5|7|8|10|12)
        echo "$year$mouth月共计有31天"
        ;;
    4|6|9|11)
        echo "$year$mouth月共计有30天"
        ;;
    2)
        if ((year % 4 == 0 && year % 100 != 0 || year % 400 == 0)) ; then 
            echo "$year$mouth月共计有29天"
        else
            echo "$year$mouth月共计有28天"
        fi
esac

select…in选择分支语句

select…in语法格式
1. 格式 
	select 变量名  in  单词列表
	do 
		shell语句
	done
	

2. 注意事项
	1> select...in语句是为了提高代码的交互性
	2> 单词列表,就是多个以空格间隔的字符串,
		当通过终端输入选择的编号,会从单词列表中选择对应的字符串赋值给“变量名”
select…in测试代码
#!/bin/bash
# your code

select num in ONE TWO THREE FOUR FIVE
do 
    echo "你的选择为$num"
done 

linux@ubuntu:~/DC22101/day04$ bash 12select.sh --> 执行脚本文件,出现以单词列表目录
1) ONE
2) TWO
3) THREE
4) FOUR
5) FIVE
#? 1		----> 输入目录对应的编号,只能输入编号,不可以输入目录名
你的选择为ONE
#? 4
你的选择为FOUR
#? 5
你的选择为FIVE
#? 6		----> 如果输入没有的编号,默认为空
你的选择为
#? 			----> 直接回车时,将目录再重新打印一次
1) ONE
2) TWO
3) THREE
4) FOUR
5) FIVE
#? ^C       ----> ctrl + c 强制退出

select … in 经常和case…in语句配合使用。

#!/bin/bash
# your code

select os in Windows macOS Linux Android IOS
do 
    case $os in
        "Windows")
            echo "打开$os操作系统"
            ;;
        "macOS")
            echo "打开$os操作系统"
            ;;
        "Linux")
            echo "打开$os操作系统"
            ;;
        "Android")
            echo "打开$os操作系统"
            ;;
        "IOS")
            echo "打开$os操作系统"
            ;;
        *)
            echo "未知的操作系统"
            ;;
    esac
done 

while循环语句

while循环语句语法格式
1. 格式
	while ((条件表达式))
	do 
		shell语句
	done
	
	while [ 表达式 ]   # while循环语句和test命令配合使用
	do
		shell语句
	done
	
	while [ true ]    # 等价于C语言中的while(1){}死循环
	do 
		shell语句     
	done 
while循环语句案例

使用while循环完成0-100直接所有数的求和。

#!/bin/bash
# your code

sum=0
i=0;

while ((i <= 100))
do 
    ((sum += i))
    ((i++))
done 

echo "0-100之间的数求和 = $sum"

sum=0
i=0
while [ $i -le 100 ]
do
    sum=`expr $sum + $i`
    ((i++))
done
echo "0-100之间的数求和 = $sum"

for循环语句

for循环的语法格式
1. 格式1:类似于C语言
	for ((表达式1;表达式2;表达式3))
	do
		shell语句4
	done
	
	执行过程:[1,2][4,3,2][4,3,2][4,3,2]......
	

2. 格式2:类似于pythne语言
	for 变量名 in 单词列表
	do 
		shell语句
	done
	
	单词列表:多个单词以空格隔开的字符串
	执行过程:依次将单词列表中的每个单词赋值给“变量名”,
		执行单词列表中的所有的单词都依次赋值给“变量名”之后,循环结束
for循环参考案例

1. 使用for循环方式,依次遍历数组中的所有的成员。

#!/bin/bash
# your code

arr=(11 33 29 44 55 99 100 104 34 66)

for (( i = 0; i < ${#arr[*]}; i++))
do 
    echo "arr[$i] = ${arr[$i]}"
done

echo "--------------------------------"

# 将数组的每个成员都在in后边展开,每循环1次从in后边取值赋值给
# 变量num,直到将in后边的所有值都进行取值之后,循环结束
i=0
for num in ${arr[@]}
do  
    echo "arr[$i] = $num"
    ((i++))
done 

2. 使用for循环的嵌套打印以下图形
*
**
***
****
*****

#!/bin/bash
# your code

for ((i=0;i<5;i++))
do 
    for ((j=0;j<=i;j++))
    do 
        # echo默认输出完成之后会打印一个换行符
        # -n : 取消换行符
        echo -n "*"
    done 
    echo ""   # 输出一个换行符
done 

for i in 0 1 2 3 4
do 
    for ((j=0;j<=i;j++))
    do 
        # echo默认输出完成之后会打印一个换行符
        # -n : 取消换行符
        echo -n "*"
    done 
    echo ""   # 输出一个换行符
done 
# seq命令:按照某种个数输入一个等差数列
# seq 起始数字 间隔大小 结束数字 ---> 从起始数字到结束数字按照间隔输出对应的数字
# seq 起始数字 结束数字 ---> 从起始数字到结束数字按照默认间隔为1输出对应的数字

for i in `seq 1 5`
do 
    for j in `seq 1 $i`
    do 
        # echo默认输出完成之后会打印一个换行符
        # -n : 取消换行符
        echo -n "*"
    done 
    echo ""   # 输出一个换行符
done 

3. 定义一个数组,如下,使用冒泡排序的方式对以下数组进行排序
arr=(11 33 29 44 55 99 100 104 34 66)。

可以使用for (())的方式实现,可以使用for in的方式实现。

方式一:
#!/bin/bash
# your code
arr=(11 33 29 44 55 99 100 104 34 66)

echo "排序之前:${arr[*]}"

for ((i = 0; i < ${#arr[*]} - 1; i++))
do 
    for ((j = 0; j < ${#arr[*]} - $i - 1; j++))
    do
        if [ ${arr[j]} -gt ${arr[j+1]} ] ; then 
            tmp=${arr[j]}
            arr[j]=${arr[j+1]}
            arr[j+1]=$tmp
        fi
    done
done 

echo "排序之后: ${arr[*]}"
方式二:
#!/bin/bash
# your code
arr=(11 33 29 44 55 99 100 104 34 66)

echo "排序之前:${arr[*]}"

x=`expr ${#arr[*]} - 2`
for i in `seq 0 $x`
do 
    y=`expr ${#arr[*]} - 2 - $i`
    for j in `seq 0 $y`
    do
        if [ ${arr[j]} -gt ${arr[j+1]} ] ; then 
            tmp=${arr[j]}
            arr[j]=${arr[j+1]}
            arr[j+1]=$tmp
        fi
    done
done 

echo "排序之后: ${arr[*]}"
方式三:
#!/bin/bash
# your code
arr=(11 33 29 44 55 99 100 104 34 66)

echo "排序之前:${arr[*]}"


for i in `seq 0 \`expr ${#arr[*]} - 2\``
do 
    for j in `seq 0 \`expr ${#arr[*]} - 2 - $i\``
    do
        if [ ${arr[j]} -gt ${arr[j+1]} ] ; then 
            tmp=${arr[j]}
            arr[j]=${arr[j+1]}
            arr[j+1]=$tmp
        fi
    done
done 

echo "排序之后: ${arr[*]}"

break和continue

break格式
	break n 
	
	1> break退出n层循环体,n大于等于1,如果n等于1,可以省略不写。
continue格式
continue n 
	
	1> continue退出n层本次循环,n大于等于1,如果n等于1,可以省略不写。
参考案例
#!/bin/bash
# your code

for i in `seq 0 5`
do 
    echo -n "#"
    if [ $i -gt 3 ] ; then 
        break 1  # 退出循环体
    fi
    echo -n "*"
done 
echo ""

for i in `seq 0 5`
do 
    echo -n "#"
    if [ $i -gt 3 ] ; then 
        continue 1  # 退出本次循环
    fi
    echo -n "*"
done 
echo ""

linux@ubuntu:~/DC22101/day04$ bash 17break.sh 
#*#*#*#*#
#*#*#*#*##

shell中的函数

shell中函数定义
1. 格式:
	function 函数名()
	{
		函数体
	}
	
2. 注意事项
	1> shell中定义的函数一般使用function进行修饰,但是也可以把function省略,
		一般再shell中定义函数时不省略function关键字。
	2> 再shell中定义的函数也要遵循先定义后似乎用的原则。
	3> shell中的函数再小括号中不需要写形参列表,函数是否具有参数最终由书写函数时决定。
	4> shell中的函数,函数名之前不需要写任何内容,表示函数是否具有返回值,
		函数是否有返回值要根据自己定义的函数决定。
shell函数调用
函数没有形参:
	函数名 
	
函数具有形参:
	函数名 实参列表(多个实参之间使用空格隔开)
在shell函数中获取获取调用函数传递的实参值
在shell函数中通过位置变量获取函数调用时传递的实参值

$0 ----> 不表示函数的名字,只表示执行脚本文件时,脚本文件的名字
$1
$2
.....
$n  ---> 如果n>=10,则将n使用花括号括起来

$*  ---> 所有的实参
$@  ---> 所有的实参
$#  ---> 所有实参的个数和
函数的返回值
1. 通过全局变量返回
	在shell的函数中定义的变量,默认也是全局的变量,
	因此可以在函数外直接使用函数内定义的全局变量

2. 通过return返回
	在shell中的函数通过return返回变量的值,只能返回0-255之间的数。
	使用$?接收函数调用时,通过return返回的函数的值

3. 通过echo命令返回
	在shell函数中调用echo命令返回,返回的返回值,可以返回任何值。
	使用命令置换符接收函数通过echo返回的函数值。
	
	变量名=`函数名 实参列表` 
	变量名=$(函数名 实参列表)
函数的参考案例
#!/bin/bash
# your code


# 1. 定义函数,函数没有参数,没有返回值
function print()
{
    echo "hello world"
}

# 2. 定义函数,函数有参数,没有返回值
function show()
{
    echo '$0='"$0"
    echo '$1='"$1"
    echo '$2='"$2"
    echo '$3='"$3"
    echo '$*='"$*"
    echo '$@='"$@"
    echo '$#='"$#"
}

# 3. 定义函数,函数有参数,有返回值,通过全局变量返回
function add_func1()
{
    sum=0   # sum是一个全局变量,在函数外也可以访问
    sum=$(($1 + $2))
}

# 4. 定义函数,函数有参数,有返回值,通过return返回,只能返回0-255之间的数
function add_func2()
{
    local sum=0   # sum是一个局部变量
    sum=$(($1 + $2))
    return $sum
}

# 5. 定义函数,通过echo返回,
function add_func3() 
{
    local sum=0 # sum是一个局部变量
    sum=$[$1 + $2]
    echo $sum
}

# 1. 函数的调用
print

# 2. 函数的调用
show aa 11 ff

# 3. 调用函数
add_func1 100 200
# 访问add_func1函数中定义的全局变量
echo "add_func1(100,200) = $sum"

# 4. 函数的调用
add_func2 10 20  # 只能返回0-255之间的数,使用$?获取通过return返回的结果
echo "add_func2(10,20) = $?"  

add_func2 100 200  # 只能返回0-255之间的数,结果为44
echo "add_func2(100,200) = $?"

# 5. 函数的调用, 通过命令置换符获取函数的返回结果
# 将函数的执行结果赋值给某个变量
sum3=`add_func3 1000 2000` 
echo "add_func3(1000,2000) = $sum3"

练习题:通过终端输入用户名,通过/etc/passwd文件判断用户是否存在,
如果存在此用户获取用户名对应的uid

1> 输⼊⽤户的名字,判断该系统上是否存在该⽤户(封装为函数get_user_line(),若⽤户存在则返回用户名/etc/passwd中的⾏号)

 提示:line=`grep "^输入的用户名"  /etc/passwd  -n | cut -d ":" -f 1`

2> 若存在该⽤户将这个⽤户名uid显示出来(封装为函数get_user_info(),将上述的函数返回的⾏号传递到这个函数中,返回uid)

 提示:uid=`head -46 /etc/passwd | tail -1 | cut -d ":" -f 3`
#!/bin/bash
# your code

read -p "请输入用户名 > " userName

function get_user_line() {
    local line=`grep "^$1"  /etc/passwd  -n | cut -d ":" -f 1`
    return $line
}

function get_user_info() {
    local uid=`head -$1 /etc/passwd | tail -1 | cut -d ":" -f 3`
    echo $uid
}

get_user_line $userName
line=$?
echo $line
if [ $line  -ne 0 ] ; then 
    echo "用户存在"
    uid=`get_user_info $line`
    echo $uid
else
    echo "用户不存在"
fi

shell编程总结

1. 变量的定义
 定义变量:变量名=初始值 变量名='初始值'    变量名="初始值"
 引用变量:${变量名} 或 $变量名
 位置变量:$n  $* $# $@

2. 数组的定义
 定义数组:数组名=(初始值列表,使用空格隔开)
 数组成员访问:${数组名[index]}    ${数组名[*]}  ${数组名[@]}    
    ${#数组名[*]}   ${#数组名[@]}   ${#数组名[index]} 
    修改成员或者添加成员:数组名[index]=新的值
   
3. 算数运算
 (())
 $[]
 expr

4. 分支语句
 if [ 表达式 ] ; then 
 
 else 
 
 fi
 
 case $变量名 in 
  常量表达式)
   ;;
  *)
   ;;
 esac
 
 select 变量名  in  单词列表(菜单选项列表)
 do
 
 done

5. 循环语句
 while [ 表达式 ]
 do 
 
 done
 
 for 变量名  in   单词列表
 do 
 
 done

6. break和continue

7. shell中的函数 
 函数定义 :
  function  函数名()
  {
  
  }
 函数调用:
  函数名
        函数名 实参表
    函数中获取函数的实参:
     $n  ---> n >= 1
     $* 
     $@
     $#
    函数的返回值:
     函数中定义全局变量
     return返回0-255直接的数,通过 $? 接收返回值
     echo输出返回值,使用命令置换符获取函数的返回值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值