在linux shell中,通常我们将一些命令写在一个文件中就算是一个shell脚本了,但是如果需要执行更为复杂的逻辑判断,我们就需要使用流程控制语句来支持了。
所谓流程控制既是通过使用流程控制语句对程序流程的选择、循环、转向和返回等进行控制。流程控制是所有编程语言分重要组成部分,linux shell同样有一套自己的流程控制语句,其中主要包括条件语句(if),循环语(for,while),选择语句(case)。

条件选择if语句

单分支

if判断条件;then

      条件为真的分支代码

fi

双分支

if 判断条件; then
条件为真的分支代码
else
条件为假的分支代码
fi

多分支

if 判断条件1; then
条件为真的分支代码
elif 判断条件2; then
条件为真的分支代码
elif 判断条件3; then
条件为真的分支代码
else
以上条件都为假的分支代码
fi

逐个条件进行判断,第一次为“真”条件时,接着执行其分支,而后结束整个if语句

条件判断case语句

case 变量引用 in        #变量的引用加$
PAT1)
分支1
;;
PAT2)
分支2
;;
...
\*)
默认分支
;;
esac

case支持glob风格的通配符:
*: 任意长度任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或b

练习
、编写脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参数,如果
指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息

#!/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

、编写脚本/root/bin/yesorno.sh,提示用户输入yes或no,并判断用户输入的
是yes还是no,或是其它信息

#!/bin/bash

read -p "Do you agree? yes or no: " ANS
if [ -z "$ANS" ] ;then
   echo "Please input yes or no"
   exit
fi
case $ANS in
[Yy]|[Yy][Ee][Ss])
   echo "Your answer is YES"
   ;;
[Nn]|[Nn][Oo])
   echo "Your answer is NO"
   ;;
*)
   echo "Your answer is fales"
esac

、编写脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型
(普通,目录,链接,其它文件类型)

#!/bin/bash

read -p "input file or dir:" choose
[ -z "$choose" ] && echo "Please input a file or dir"
if [ -d "$choose" ] ;then
   echo "$choose is directory"
elif [ -L "$choose" ] ;then
   echo "$choose is a link"
elif [ -f "$choose" ] ;then
   echo "$choose is a common file"
else
   echo "$choose is other type"
fi

、编写脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数

#!/bin/bash

read -p "input a digit:" NUM
if [[ "$NUM" =~ ^[0-9]+$ ]] ;then
   echo "$NUM is a int"
fi

循环

循环执行

将某代码段重复运行多次

重复运行多少次

循环次数事先已知

循环次数事先未知

有进入条件和退出条件

for, while, until

for循环

for 变量名 in 列表;

do

   循环体

done

执行机制:

    依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直 到列表中的元素耗尽,循环结束
列表生成方式:
() 直接给出列表
for num in ;do echo The number is $num ;done
The number is
The number is
The number is
The number is
The number is () 整数列表:
(a) {start..end}
for num in {....};do echo The numberis $num ;done
The numberis
The numberis
The numberis
The numberis
(b) $(seq [start [step]] end)
for num in `seq `;do echo The number is $num ;done
The number is
The number is
The number is () 返回列表的命令 $(COMMAND)
() 使用glob,如:*.sh
for num in "/root/bin/*.sh";do echo The filename is $num ;done
The filename is /root/bin/*.sh
(5) 变量引用; $@独立, $*整体(位置变量)

多行重定向

练习:
用for实现
、打印国际象棋
for i in {..};do
for j in {..};do
if [ $[i%] -eq ];then
echo -e "\033[1;41m \033[0m\e[1;43m \e[0m\c"
else
echo -e "\e[1;43m \e[0m\e[1;41m \e[0m\c"
fi
done
echo
done \c=-n默认不转行 \e \e[0m=\ \[0m颜色提示符 、添加10个用户user1-user10,密码为magedu
for i in {..};do
if id $i &> /dev/null ;then echo "user$i is exist"
else
useradd user$i &>/dev/null
echo "magedu" | passwd --stdin user$i &>/dev/null
echo "user $i add successful"
fi
done 注:批量删除用户for i in {..};do userdel -r(删除家目录) user$i;done 、/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,
以K开头的输出为文件加stop,以S开头的输出为文件名加start,如K34filename stop
S66filename start
#!/bin/bash
for i in $(ls /etc/rc.d/rc3.d/);do
if [[ $i =~ ^K.* ]];then
echo "$i stop"
elif [[ $i =~ ^S.* ]];then
echo "$i start"
fi
done
、编写脚本,提示输入正整数n的值,计算1++…+100的总和
#!/bin/bash declare -i sum= n=
for i in {..};do
let sum=sum+i | sum+=i
done
echo sum=$sum
unset sum
、计算100以内所有能被3整除的整数之和
#!/bin/bash
sum=
for i in {..};do
if [ $[$i%] -eq ];then
let sum+=$i
fi
done
echo $sum
、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态
net=192.168.
for i in {..};do
{ if ping -c1 -w1 $net .$i &> /dev/null ;then
echo $net.$i is up
else
echo $net.$i is down
fi; } & 并行在后台执行
done
wait 、打印九九乘法表
#!/bin/bash for i in {..};do
for j in `seq $i`;do
result=$[$j*$i]
echo -e "$j*$i=$result \c"
done
echo
done 、在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字
母,如:1AbCdeFgH.html
取随机字母openssl rand -base64 | tr -dc '[:alpha:]' | head -c8
、打印等腰三角形
*的个数=line*-
空格=总line-
当前line
#!/bin/bash
read -p "Please input lines:" L
for i in `seq ${L}`;do
for (( j=${L};j>i;j-- ));do
echo -n " "
done
for j in `seq $i`;do
echo -n "*"
done
for (( n=;n<i;n++ ));do
echo -n "*"
done
echo " "
done

 打印等腰三角形并且颜色随机

#!/bin/bash
read -p "Please input lines:" L
for i in `seq ${L}`;do for j in `seq $[$L-i]`;do
echo -n " "
done
for k in `seq $[i*-]`;do
let color=$RANDOM%+
echo -ne "\e[1;5;${color}m*\e[0m"
done
echo
done

while循环

while 条件;do
循环体
done
条件(CONDITION):循环控制条件;进入循环之前,先做一次判断;每次循环之后会再次做判断;条件为"ture",
则执行一次循环;直到条件测试状态为“false”终止循环。 因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地 被修正 进入条件:CONDITION为true 退出条件:CONDITION为false
练习:
1、编写脚本,求100以内所有正奇数之和
#!/bin/bash
declare -i sum=
i=
while [ $i -le ];do
let sum=sum+i
let i=i+
done
echo sum=$sum 、编写脚本,提示请输入网络地址,如192.168.0.,判断输入的网段中主机
在线状态,并统计在线和离线主机各多少

#!/bin/bash

net=192.168.140
let num=1
x=0(up的主机)
y=0(down的主机数)
while [ ${num} -le 254 ];do
ping -c1 -w1 "${net}.${num}" &>/dev/null
  if [ $? -eq 0 ];then
    echo "${net}.${num} is up"
    x=$(($x+1))
  else
    echo "${net}.${num} is down"
    y=$(($y+1))
  fi
num=$(($num+1))
done
echo "total ${x} hosts are up"
echo "total ${y} hosts are down "

、编写脚本,打印九九乘法表

#!/bin/bash

declare -i i=1
while [ $i -le 9 ];do
    declare -i j=1
    while [ $j -le $i ];do
       result=$[$i*$j]
       echo -e "${j}x${i}=$result\t\c" \t是产生空格并对齐;\c是不换

let j++

done
    echo
    let i++
done

、编写脚本,利用变量RANDOM生成10个随机数字,输出这个数字,并显
示其中的最大值和最小值

#!/bin/bash

declare -i a=0
max=0
min=$RANDOM
while [ $a -le 9 ];do
num=$RANDOM
  if [ $num -le $max ];then
    if [ $num -le $min ];then
      min=$num
      fi
  else
      max=$num
  fi
  let a++:q!:
done
echo "the min number is $min,the max number is $max"

、编写脚本,实现打印国际象棋棋盘

#!/bin/bash

let i=0
while [ $i -le 15 ];do
  for ((j=0;j<4;j++));do
    if [ $[i%4] -eq 0 -o $[i%4] -eq 1 ];then
      echo -e "\033[1;41m \033[0m\033[1;47m \033[0m\c"
    else
      echo -e "\033[1;47m \033[0m\033[1;41m \033[0m\c"

    fi
  done
  echo
  let i++
done

、后续六个字符串:efbaf275cd、4be9c40b8b、44b2395c46、
f8c8873ce0、b902c16c8b、ad865d2f63是通过对随机数变量RANDOM随机
执行命令: echo $RANDOM|md5sum|cut –c1- 后的结果,请破解这些
字符串对应的RANDOM值while循环

 until循环

until CONDITION; do
循环体
done
进入条件: CONDITION 为false
退出条件: CONDITION 为true

循环控制语句continue

用于循环体中
continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
...
done

循环控制语句brek

用于循环体中
break [N]:提前结束第N层循环,最内层为第1层
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
break
fi
CMDn
...
done

创建无限循环

while true; do

  循环体

done

until false; do

   循环体

Done

练习
、每隔3秒钟到系统上获取已经登录的用户的信息;如果发现用户hacker登录,
则将登录时间和主机记录于日志/var/log/login.log中,并退出脚本
#!/bin/bash

until `who | grep -o "^usr\b" &>/dev/null`;do
    sleep 3
done
echo "user is logining"
who | grep "user" >> /data/login.sh:q!

、随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出

#!/bin/bash

i=$[$RANDOM%11]
while read -p "please input a number:" a;do
  [[ $a =~ ^[0-9]+$ ]] || { echo "please input a dight:1-10";continue; }
  if [ $i -gt $a ];then
    echo little
  elif [ $i -lt $a ];then
    echo more
  else
    echo right
    break
  fi
done

、用文件名做为参数,统计所有参数文件的总行数

if [ $# -eq 0 ];then  $#是所有未知变量
  echo "please input file path"
 else
  until [ -z "$1" ];do -z判断文件是否为空
    echo "tongji file:$1"
    echo "the file total line are: `wc -l $1 | cut -d " " -f1`“
    echo
    shift
done
echo "finish"
fi

、用二个以上的数字为参数,显示其中的最大值和最小值

函数:function

是由若干条shell命令组成的语句块,实现代码重用和模块化编程;函数只有被调用才会执行

语法1:

function func_name {

  函数体

}

语法2::

func_name() {

  函数体

}

注意:函数中变量的生效范围是当前所在shell

函数的生命周期:被调用时创建,返回时终止

函数在使用前必须定义,因此应将函数定义放在脚本开始部分,直至shell首次发现它后才能使用,调用函数时就像使用命令一样调用

return #:在函数中使用,跳出函数,返回值 #;如果没有定义退出返回值则函数的默认返回值为函数中最后一条命令的返回值

local var:声明函数为本地变量,只在函数内部生效

declare

  -f func_name 查看指定函数

  -xf func_name 声明函数的生效范围为全局 == export -f func_name

  -i 声明变量为数字

  -g 在函数中使用,声明变量为普通变量

  declare 在函数中用隐式使用了local,定义的变量为本地变量

函数的递归调用:在函数中调用函数本身

fork炸弹

bome() { bome|bome& }; bome

编写脚本copycmd.sh

  • (1) 提示用户输入一个可执行命令名称;
  • (2) 获取此命令所依赖到的所有库文件列表;
  • (3) 复制命令至某目标目录(例如/mnt/sysroot)下的对应路径下;
    • 如:/bin/bash ==> /mnt/sysroot/bin/bash
  • (4) 复制此命令依赖到的所有库文件至目标目录下的对应路径下;(5)每次复制完成一个命令后,不要退出,而是提示用户键入新的要复制的命令,并重复完成上述功能;直到用户输入quit退出;
    • 如:/lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2
#!/bin/bash
. my_functions
Ddir="/mnt/sysroot"
[ ! -d "$Ddir" ] && mkdir "$Ddir" cpbin() {
cmddir=`echo "$Cmd_path" |grep -o ".*/\b"`
[ ! -d "${Ddir}${cmddir}" ] && mkdir -p "${Ddir}${cmddir}"
cp -n "$Cmd_path" "${Ddir}${cmddir}"
} libcp() {
echo "$Lib_path" |while read line ;do
libdir=`echo "$line" |grep -o ".*/\b"`
[ ! -d "${Ddir}${libdir}" ] && mkdir -p "${Ddir}${libdir}"
cp -n "$line" "${Ddir}${libdir}" 2>/dev/null
done
} while read -p "Input a cmd. (quit): " CMD ;do
if [ "$CMD" == 'quit' ] ;then echo "Think you! Bye bye."; break; fi
if ! which "$CMD" &>/dev/null ;then
echo "not find $CMD, please input again."
failed "copy $CMD failed."
continue
fi
Cmd_path=`which $CMD |grep -o "/.*"`
Lib_path=`ldd $Cmd_path |sed -nr 's#.*[[:space:]]+(/.*) .*#\1#p'`
cpbin
libcp
success "copy $CMD Complete."
done

求斐波那契数列的第N个数

#!/bin/bash
feibo() {
if [ $1 -eq 0 ] ; then
echo 0
elif [ $1 -eq 1 ] ;then
echo 1
else
echo $[`feibo $[$1-1]`+`feibo $[$1-2]`]
fi
} read -p "please a num: " n

求N的阶乘

#!/bin/bash
fact() {
if [ $1 -eq 0 -o $1 -eq 1 ] ;then
echo 1
else
echo $[$1*`fact $[$1-1]`]
fi
} fact $1

shell脚本编程进阶的更多相关文章

  1. Shell—脚本编程进阶

    shell脚本进阶之条件语句 条件选择if语句 https://www.runoob.com/?s=shell&page=1 https://www.cnblogs.com/flylinux/ ...

  2. shell脚本编程进阶及RAID和LVM应用1

    bash脚本编程 脚本文件格式: 第一行,顶格写: #!/bin/bash 注释行:#开头 代码注释:写清楚注释 规范写脚本:适度缩进,添加空白行 编程语言:有编程语法格式,库,算法和数据结构 编程思 ...

  3. shell脚本编程进阶及RAID和LVM应用2

    文件测试 存在性测试 -a FILE 这个选项的效果与-e 相同.但是它已经被弃用了,并且不鼓励使用 -e FILE 文件的存在性测试,存在则为真,否则为假 例:~]# [ -e /etc/rc.d/ ...

  4. 《Linux命令行与shell脚本编程大全》 第二十七章 学习笔记

    第二十七章:shell脚本编程进阶 监测系统统计数据 系统快照报告 1.运行时间 uptime命令会提供以下基本信息: 当前时间 系统运行的天数,小时数,分钟数 当前登录到系统的用户数 1分钟,5分钟 ...

  5. 《Linux命令行与shell脚本编程大全 第3版》

    第一部分 Linux 命令行 第1章  初识Linux she1.1   什么是Linux 21.1.1 深入探究Linux 内核 31.1.2 GNU 工具 61.1.3 Linux 桌面环境 81 ...

  6. Shell脚本编程30分钟入门

    Shell脚本编程30分钟入门 转载地址: Shell脚本编程30分钟入门 什么是Shell脚本 示例 看个例子吧: #!/bin/sh cd ~ mkdir shell_tut cd shell_t ...

  7. Linux shell脚本编程(三)

    Linux shell脚本编程 流程控制: 循环语句:for,while,until while循环: while CONDITION; do 循环体 done 进入条件:当CONDITION为“真” ...

  8. Linux shell脚本编程(二)

    Linux shell脚本编程(二) 练习:求100以内所有偶数之和; 使用至少三种方法实现; 示例1: #!/bin/bash # declare -i sum=0 #声明一个变量求和,初始值为0 ...

  9. Linux shell脚本编程(一)

    Linux shell脚本编程: 守护进程,服务进程:启动?开机时自动启动: 交互式进程:shell应用程序 广义:GUI,CLI GUI: CLI: 词法分析:命令,选项,参数 内建命令: 外部命令 ...

随机推荐

  1. 初学java4 循环的使用

    for循环 for(初始条件;循环终止条件;循环结束后所执行代码){ 循环体 } while循环 while(循环终止条件){ 循环体 } do while循环 do{ }while(循环终止条件);

  2. JDK + Tomcat 安装 + 制作自定义镜像【第 3 篇 系统镜像】

    [第 1 篇 JDK]:https://www.cnblogs.com/del88/p/11842387.html[第 2 篇 Tomcat]:https://www.cnblogs.com/del8 ...

  3. JavaScript之排序算法

    一.冒泡排序 原理:1.比较相邻的元素.如果第一个比第二个大,就交换两个数:2.对每一对相邻元素重复做步骤一,从开始第一对到结尾的最后一对,该步骤结束会产生一个最大的数:3.针对所有的数重复以上的步骤 ...

  4. VMware虚拟机与Linux Centos7下载及安装教程

    1.CentOS下载CentOS是免费版,推荐在官网上直接下载,网址:https://www.centos.org/download/ DVD ISO:普通光盘完整安装版镜像,可离线安装到计算机硬盘上 ...

  5. python笔记:学习设置Python虚拟环境+配置 virtualenvwarpper+创建Python3.6的虚拟环境+安装numpy

    虚拟环境它是一个虚拟化,从电脑独立开辟出来的环境.就是借助虚拟机docker来把一部分内容独立出来,我们把这部分独立出来的东西称作“容器”,在这个容器中,我们可以只安装我们需要的依赖包,各个容器之间互 ...

  6. Vue介绍:vue项目搭建

    一.环境搭建 二.项目创建 三.认识项目 四.项目功能 一.环境搭建 *安装node 官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/ *安装cnpm npm insta ...

  7. Linux的.a、.so和.o文件及链接时的命名

    在说明Linux的.a..so和.o文件关系之前,先来看看windows下obj,lib,dll,exe的关系 windows下obj,lib,dll,exe的关系 lib是和dll对应的.lib是静 ...

  8. leaflet的使用

    LeafLet 简单使用 WangKane 关注  0.4 2018.12.03 16:08 字数 887 阅读 3773评论 0喜欢 4 Leaflet 使用 最近在Angular项目中,用到了地图 ...

  9. django缓存--缓存加数据库型

    4.缓存+数据库Session 数据库用于做持久化,缓存用于提高效率   a. 配置 settings.py       SESSION_ENGINE = 'django.contrib.sessio ...

  10. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (LCT维护深度)

    要维护深度,就维护一下size就行了.access一下x,那么从根->x这一条链就独立成为一棵splay,那么splay的size节点数就是x的深度. 删边的时候直接access一下,splay ...