一, 条件选择 if 语句
选择执行:
注意: if 语句可嵌套
单分支
if 判断条件; then
条件为真的分支代码
fi
双分支
if 判断条件; then
条件为真的分支代码
else
条件为假的分支代码
fi
多分支
if 判断条件 1; then
条件为真的分支代码
elif 判断条件 2; then
条件为真的分支代码
elif 判断条件 3; then
条件为真的分支代码
else
以上条件都为假的分支代码
fi
例子:
1, 编写脚本 / root/bin/createuser.sh, 实现如下功能: 使用一个用户名做为参数, 如果指定参数的用户存在, 就显示 其存在, 否则添加之; 显示添加的用户的 id 号等信息
- VIM createuser.sh
- #!/bin/bash
- read -p "please input username:" username
- useradd $username &> /dev/null
- if [ $? -eq 0 ];then
- echo "add $username user" && id $username
- else
- echo "the user already exits"
- fi
2, 编写脚本 / root/bin/checkint.sh, 判断用户输入的参数是 否为正整数
- VIM checkint.sh
- #!/bin/bash
- read -p "please input a digit:" int
- if [[ $int =~ (^[0-9]*[1-9][0-9]*$) ]];then
- echo "this digit is positive integer"
- else
- echo "this digit is not positive integer"
- fi
二, 条件判断 case 语句
语法格式:
case 变量引用 in
PAT1)
分支 1 ;;
PAT2)
分支 2 ;;
...
*)
默认分支 ;;
esac
3, 编写脚本 / root/bin/yesorno.sh, 提示用户输入 yes 或 no, 并判断用户输入的是 yes 还是 no, 或是其它信息
- VIM yesorno.sh
- #!/bin/bash
- read -p "can i help you? yes or no" ans
- case $ans in
- [yY][eE][sS]|[yY])
- echo "ok,come on"
- ;;
- [nN][oO]|[nN])
- echo "no,thanks"
- ;;
- *)
- echo "byebye"
- ;;
- esac
4, 编写脚本 / root/bin/filetype.sh, 判断用户输入文件路径 , 显示其文件类型 (普通, 目录, 链接, 其它文件类型)
- VIM filetype.sh
- #!/bin/bash
- read -p "please input file path:" path
- a=`ls -l $path|grep -o "^."` #脚本里面不能使用别名, 所以用 ls -l
- case $a in
- -)
- echo "common file"
- ;;
- d)
- echo "directory file"
- ;;
- l)
- echo "linked file"
- ;;
- *)
- echo "other file"
- ;;
- esac
三, for 循环
语法格式:
for 变量名 in 列表; do
循环体
done
执行机制:
依次将列表中的元素赋值给 "变量名"; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽, 循环结束
for 循环列表生成方式:
(1) 直接给出列表
(2) 整数列表:
- (a){start..end}
- (b)$(seq [start [step]] end)
(3) 返回列表的命令
$(COMMAND)
(4) 使用 glob, 如:*.sh
(5) 变量引用;
$@, $*
5, 编写脚本, 提示输入正整数 n 的值, 计算 1+2+...+n 的总和
- #!/bin/bash
- read -p "please input a positive integer:" n
- i=1
- sum=0
- for i in `seq 1 $n`;do
- if [[ $n =~ (^[0-9]*[1-9][0-9]*$) ]];then #判断 n 是否为正整数
- let sum+=i
- else
- echo "a wrong int" && exit
- fi
- let i++
- done
- echo "sum is $sum"
6, 计算 100 以内所有能被 3 整除的整数之和
- #!/bin/bash
- sum=0
- i=1
- for i in {1..100};do
- if [ $[$i%3] -eq 0 ];then
- let sum+=i
- fi
- let i++
- done
- echo $sum
7, 打印九九乘法表
- #!/bin/bash
- for i in {1..9};do
- for j in `seq 1 $i`;do
- echo -n "$i*$j=$[i*j]"
- done
- echo
- done
8, 打印等腰三角形
- #!/bin/bash
- . functions
- read -p "please input line:" line
- is_digit $line
- #i=* 的个数 s = 空格个数 l = 当前行数
- [ $? -ne 0 ] && exit
- #循环打印
- for l in `seq 1 $line`;do
- for s in `seq 1 $[$line-$l]`;do
- echo -en " "
- done
- for i in `seq 1 $[2*$l-1]`;do
- if [ $i -eq 1 ];then
- color=$[RANDOM%7+31] #定义一个 31 到 37 的随机颜色
- echo -en "\e[1;${color};5m*\e[0m" #1 代表高亮显示, 5m 代表闪烁
- elif [ $i -eq $[$l*2-1] ];then
- echo -en "\e[1;${color};5m*\e[0m"
- else
- echo -en "*"
- fi
- done
- echo
- done
四, while 循环
语法格式:
while CONDITION; do
循环体
done
CONDITION: 循环控制条件; 进入循环之前, 先做一次判断; 每一次循环之后会再次做判断; 条件为 "true", 则执行一次循环; 直到条件测试状态为 "false" 终止循环
因此: CONDTION 一般应该有循环控制变量; 而此变量的值会在循环体不断地被修正
进入条件: CONDITION 为 true
退出条件: CONDITION 为 false
9, 编写脚本, 求 100 以内所有正奇数之和
- #!/bin/bash
- i=1
- sum=0
- while [ $i -le 100 ];do
- if [ $[$i%2] -ne 0 ];then
- let sum+=i
- fi
- let i++
- done
- echo "sum is $sum"
10, 编写脚本, 利用变量 RANDOM 生成 10 个随机数字, 输出 这个 10 数字, 并显示其中的最大值和最小值
- #!/bin/bash
- i=1
- a=$RANDOM
- max=$a
- min=$a
- while [ $i -le 10 ];do
- [ $max -lt $a ] && max=$a
- [ $min -gt $a ] && min=$a
- a=$RANDOM
- echo "$a"
- let i++
- done
- echo "max is $max"
- echo "min is $min"
11, 编写脚本, 实现打印国际象棋棋盘
- #!/bin/bash
- red="\e[41m \e[0m"
- white="\e[47m \e[0m"
- for i in `seq 1 8`;do #这里定义了一个 8 行的棋盘
- if [ $[i%2] -eq 0 ];then #判断是否为偶行
- for j in {1..4};do #四个偶数行就循环四遍红白色
- echo -en "$red$white"
- done
- else
- for j in {1..4};do #四个奇数行循环白红行
- echo -en "$white$red"
- done
- fi
- echo
- done
12, 后续六个字符串: efbaf275cd,4be9c40b8b, 44b2395c46,f8c8873ce0,b902c16c8b,ad865d2f63 是通过对随机数变量 RANDOM 随机执行命令: echo $RANDOM|md5sum|cut -c1-10 后的结果, 请破解这些字符串对应的 RANDOM 值
- #!/bin/bash
- key_num_array=(efbaf275cd 4be9c40b8b 44b2395c46 f8c8873ce0 b902c16c8b ad865d2f63) #将这些字符串赋值到数组里, 方便调用
- for true_num in `seq 0 65535`;do #RANDOM 值为 0~65535
- key_num=`echo $true_num | md5sum | cut -c 1-10`
- for num in ${key_num_array[*]}; do
- if [ "$key_num" == "$num" ];then
- echo "$num --> $true_num"
- fi
- done
- done
五, Until 循环 (与 while 条件相反, 比较少用)
语法格式:
until CONDITION; do
循环体
done
进入条件: CONDITION 为 false
退出条件: CONDITION 为 true
13, 每隔 3 秒钟到系统上获取已经登录的用户的信息; 如果发 现用户 hacker 登录, 则将登录时间和主机记录于日志 /var/log/login.log 中, 并退出脚本
- #!/bin/bash
- until who |grep "^hacker\>";do
- sleep 3
- done
- who|egrep -o "^hacker.*"|sed -r 's/^hacker[[:space:]]+'//>> /App/hacker.log #小编这里记录于这个路径
- echo "you should logout"| mail hacker
14, 随机生成 10 以内的数字, 实现猜字游戏, 提示比较大或小 , 相等则退出
- #!/bin/bash
- num=$[$RANDOM%10+1]
- read -p "please guess:" i
- until [ $num -eq $i ]; do
- if [ $i -lt $num ]; then
- echo "less,guess again"
- else
- echo "bigger,guess again"
- fi
- read -p "please guess:" i
- done
- echo "guess succeed!";exit
六, 循环控制语句 continue
用于循环体中
continue [N]: 提前结束第 N 层的本轮循环, 而直接进入下一 轮判断; 最内层为第 1 层
语法格式:
- while CONDTIITON1; do
- CMD1
- ...
- if CONDITION2; then
- continue
- fi
- CMDn
- ...
- Done
举例奇数相加并跳过 51
- #!/bin/bash
- for((i=1,sum=0;i<=100;i++));do #奇数相加
- [ $i -eq 51 ] && continue #结束本轮循环, 就是跳过 51 执行下面的奇数 53
- [ $[i%2] -eq 1 ] && let sum+=i
- done
- echo "sum is $sum"
- unset i sum
七, 循环控制语句 break
用于循环体中
break [N]: 提前结束第 N 层循环, 最内层为第 1 层
语法格式:
- while CONDTIITON1; do
- CMD1
- ...
- if CONDITION2; then break
- fi
- CMDn
- ...
- Done
举例结束点餐
- #!/bin/bash
- cat <<EOF
- 1 yangroufan
- 2 mifan
- 3 hulatang
- 4 jiaozi
- 5 lamian
- 6 huimian
- 7 exit
- EOF
- while true;do
- read -p "please choose:" wufan
- case $wufan in
- 1|4)
- echo "price 20"
- ;;
- 2|5)
- echo "price 15"
- ;;
- 3|6)
- echo "price 10"
- ;;
- 7)
- break #输入 7 就直接退出这个循环
- ;;
- *)
- echo "no this option"
- ;;
- esac
- done
八, 循环控制 shift 命令
shift [n]
用于将参量列表 list 左移指定次数
参量列表 list 一旦被移动, 最左端的那个参数就从列表中删 除. while 循环遍历位置参量列表时, 常用到 shift
- #!/bin/bash
- while (( $#> 0 ));do
- echo $*
- shift
- done
九, select 与 case
select 循环主要用于创建菜单, 按数字顺序排列的, 它是个无限循环, 因此要记住用 break 命令退 出循环, 或用 exit 命令终止脚本. 也可以按 ctrl+c 退出循环
举例创建菜单并退出菜单:
- #!/bin/bash
- select menu in yangroufan gaojiaofan huimian hulatang quit;do
- case $REPLY in
- 1|3)
- echo "price is 20"
- ;;
- 2|4)
- echo "price is 15"
- ;;
- 5)
- break
- ;;
- *)
- echo "no this option"
- ;;
- esac
- done
select 经常和 case 联合使用
十, 信号捕捉 trap : 捕捉到信号后自定义处理
trap '触发指令' 信号
自定义进程收到系统发出的指定信号后, 将执行触发指令 , 而不会执行原操作 trap '' 信号 忽略信号的操作
trap '-' 信号 恢复原信号的操作
trap -p 列出自定义信号操作
举例打印数字捕捉信号
- #!/bin/bash
- trap 'echo press ctrl+c' 2 #提示按了 ctrl+c
- for((i=0;i<10;i++));do
- sleep 1
- echo $i
- done
- trap '' INT #不提示
- for((i=10;i<15;i++));do
- sleep 1
- echo $i
- done
- trap '-' 2 #恢复 ctrl+c 的停止作用
- for((i=15;i<20;i++));do
- sleep 1
- echo $i
- done
来源: http://www.bubuko.com/infodetail-2827977.html