第1章 shell基础下

1.1read基础命令

shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入中获得,read为bash内置命令。

常见语法格式

read[参数] [变量名]

1.1.1-p

-p=prompt:设置提示信息

[root@CC ~]# read -p "请输入两个数字" V1 V2

请输入两个数字1 2

[root@CC ~]# echo $V1 $V2

1 2

1.1.2-t

设置输入等待时间,单位默认为秒

[root@CC ~]# read -p "请输入两个数字" -t 5

请输入两个数字[root@CC ~]#

1.1.3-n计数

read -n个数,设置read命令计数输入的字符,当输入的字符数目达到预定数目时自动退出,并将输入的数据赋值给变量。

[root@CC ~]# read -p "请输入两个数字"  -n 5 -t 10 a b c

请输入两个数字1 2 3[root@CC ~]# echo $a

1

[root@CC ~]# echo $b

2

[root@CC ~]# echo $a $b $c

1 2 3

案例:实现read 基本读入功能

[root@CC scripts]# read -t 10 -p "输入一个数字:" num

输入一个数字:12

[root@CC scripts]# echo $num

12

1.2if 条件语句

对于if条件语句,简单地说,其语义类似于汉语里的“如果。。那么。。”。if条件语句是linux运维人员必掌握的知识!

1.2.1if条件语句的语法

  1. 单分支结构:

第一种语法:

if <条件表达式>

then

指令

fi

第二种语法:

if <条件表达式>;then

指令

fi

上文的“<条件表达式>"部分可以是test,[],[[]],(())等条件表达式,甚至可以直接使用命令作为条件表达式。每个if条件语句都以if开头,并且带有then,最后以fi结束。

第二种语法中的分号相当于命令换行,上面的两种语法含义是相同的。

条件语句还可以嵌套(即if条件句里面还有if条件句),注意每个if条件句中都要有一个与之对应的fi,每个if和它下面最近的fi成对搭配,语法如下表示:

if <条件表达式>

then

if <条件表达式>

then

fi

fi

特殊用法:

文件条件表达式[-f "$file1"]&&echo 1就等价于下面的if条件语句。

if [ -f  "$file1"];then

echo 1

fi

记忆方法:

为了便于大家记忆if单分支语句的语法,老男孩给出了形象的语法描述。if条件语句单分支的中文编程就相当于一个女孩对你说:

如果<你有房>

那么

我就嫁给你

果如

案例1 比较两个数字的大小

read -p "请输入两个字:" x y

#no.1 判断是否为两个数字

[ -z "$x" -o -z"$y" ] &&\

echo "错误:输入两个整数"  &&\

exit 1

#no.2 判断是数字

if [   -z  "`echo $x|sed 's#[0-9]##g'` " -a   -z " `echo $y|sed's#[0-9]##g'` " ]

then 

echo " 错误:请输入整数 "

exit 2

fi

exit 2

fi

#no.3 比较数字大小

if [ $x -gt $y ]

then 

    echo "$x > $y"

    

else

 if [ $x -lt $y ]

 then

    echo "$x<$y"

else

 

   echo "$x=$y"

fi

检查输出结果

[root@CC tmp]# sh 比较.sh

请输入两个字:2 1

2 > 1

[root@CC tmp]# sh 比较.sh

请输入两个字:1 1

1=1

[root@CC tmp]# sh 比较.sh

请输入两个字:1 2

1<2

1.2.2 双分支结构

if 条件语句的单分支结构主体就是“如果.....,那么.......",而if条件语句的双分支结构则为”如果....,那么.....,否则,........."

if条件语句的双分支结构语法为:

if<条件表达式>

then

  指令集1

else

  指令集2

fi

例:

if [ $x -eq $y ]

then

    echo"$x = $y"

else

    echo"$x < $y"

fi

1.2.3多分支语句

if条件语句多分支的主体为“如果.....,那么.....,否则如果........,那么,否则如果........,那么....,否则...."

if条件语句多分支:

if  <条件表达式1>

then

   指定2

else

   指定3

fi

提示:

  1. 多分支elif 的写法,每个elif都要带有then.

  2. 注意结尾的else后面没有then

fi

#no.3 比较数字大小

if [ $x -gt $y ]

then 

    echo"$x > $y"

    

else

 if [ $x -lt$y ]

 then

    echo"$x<$y"

else

 

   echo"$x=$y"

fi

 

fi

1.3case

case条件语句相当于分支的if/elif/else 条件语句,但是它比这些条件语句看起来更规范更工整,常被应用于实现系统服务启动脚本等企业应用场景中。

1.3.1case条件语句的语法

case条件语句的语法格式为:

case "常量” in

值1)

指令1..

;;

值 2)

指令2..

;;

*)

指令 3..

esec

说明:当变量的值等于值1,执行指令1;等于值2时执行指令2,以此类推;如果都不符合,则执行“*)”后面的指令,即指令3.此外,注意不同行内容的缩进距离。

 

case 语句小结

  1. 语句就相当于多分支的if语句,case 语句的优势是更规范,易读。

  2. 语句适合变量的值少,且为固定的数字或字符串。{1,2,3}或{start,stop,restart}

  3. 系统服务启动脚本传参的判断多用case语句,多参考rpcbind/nfs/crond脚本

echo -e "\033[30m 黑色字cc trainning \033[0m"

echo -e "\033[31m 红色字cc trainning \033[0m"

echo -e "\033[32m 绿色字cc trainning \033[0m"

echo -e "\033[33m ×××字cc trainning \033[0m"

echo -e "\033[34m 蓝色字cc trainning \033[0m"

echo -e "\033[35m 紫色字cc trainning \033[0m"

echo -e "\033[36m 天蓝字cc trainning \033[0m"

echo -e "\033[37m 白色字cc trainning \033[0m"

echo -e "\033[40;37m 黑底白字 welcome to cc1\033[0m"

echo -e "\033[41;37m 红底白字 welcome to cc2\033[0m"

echo -e "\033[42;37m 绿底白字 welcome to cc3\033[0m"

echo -e "\033[43;37m 黄底白字 welcome to cc4\033[0m"

echo -e "\033[44;37m 蓝底白字 welcome to cc5\033[0m"

echo -e "\033[45;37m 紫底白字 welcome to cc6\033[0m"

echo -e "\033[46;37m 天蓝白字 welcome to cc7\033[0m"

echo -e "\033[47;30m 白底黑字 welcome to cc8\033[0m"

使用时直接复制粘贴即可

实例应用

echo " Usage : $0 content{red|green|blue|yellow}"

fi 

       

case "$2" in

   red|RED|Red)

        echo-e "\033[31m $1 \033[0m"

        ;;

   green|GREEN)

        echo-e "\033[32m $1 \033[0m"

        ;;

    blue)

        echo-e "\033[34m $1 \033[0m"

        ;;

    yellow)

        echo-e "\033[33m $1 \033[0m"

        ;;

    *)

        echo"Usage:$0 content {red|green|blue|yellow}"

esac

1.5循环语句(while/for)

1.5.1循环语句语法

while 条件句

while 条件

do

  指令

done

1.5.2for 循环结构语法

for 变量名 in 变量取值列表

  do

指令...

done

 

 

 

打印列表元素

for n in {1..5}

do

echo $n

done

[root@CC scripts]# sh for1.sh

1

2

3

4

5

1.5.3while

 while条件句

while 条件

do

   指令

done

 

#!/bin/sh

while ture

  do

uptime

sleep 2

done    #死循环

实例:守护进程问题

while true

do

 uptime    echo -e "\033[31m  date+%F \033[0m"

 usleep100000

 done     

 

1.6防止脚本执行中断的方法

  1. 分离ctrl+a+d 查看screen -ls进入screen -r num

  2. 循环的特长是执行守护进程以及我们希望循环不退出持续执行,用于频率小于1分钟循环处理(crond),其他的while循环几乎都可以被for循环替代。

  3. 语句可以被if语句替换,一般在系统启动脚本传入少量固定规则字符串用case语句。其他普通判断多用if。

  4. 一句话,if ,for语句最常用,其次while(守护进程),case(服务启动脚本)。

  5. 通过系统环境变量$RANDOM

[root@cc34-moban ~]# echo $((RANDOM%9))   #输出0~9之间的随机数

4

 [root@cc34-moban~]# echo $((RANDOM%9))$((RANDOM%9))  #输出00~99之间的随机数

51

[root@cc34-moban ~]# echo $RANDOM|md5sum   #随机数长短不一,可以用md5sum命令统一格式化

19121aca287a586799549aa689c8e526  -

between 0 and32767

多种取随机数方法组合起来密码更随机

 

  1. 通过openssl产生

  2. 通过时间获取随机数

echo $(date +%N

uuid码有硬件,时间,机器当前运行信息等组成,理论上在互联网中是唯一的。

[root@cc34-moban ~]# uuidgen

5fc2a0b4-4ddf-4663-9022-ce3647ba8533

1.9break continue exit return

1.9.1break continue exit对比

命令

说明

break n   

n表示跳出循环的层数,如果省略n表示跳出整个循环。

continue n

n表示退出到第n层继续循环,如果省略n表示跳过本次循环,忽略本次循环的剩余代码,进入循环的卜次循环

exit n

退出当前shell程序,n为返回值,n也可以省略,在下一个shell

里通过$?接收这个n的值。

return n

用在函数里,作为函数的返回值,用于判断函数执行是否正确

和exit一样,如果函数里有循环,也会直接退出循环,退出函数。

break跳出整个循环,继续循环外后而的程序执行。

continue结束本次循环,继续下一次循环。

exit退出核个脚本

 

第2章 shell脚本的调试

2.1shell脚本调试技巧

调试技巧1:使用dos2unix处理脚本

从windows编辑的脚本到Linux下需要使用这个命令。

dos2unix windows.sh

 

调试技巧2:使用echo命令调试

在变量读取或修改的前后加入echo$变量。也可在后面使用exit退出脚本这样可以不用注释后面的代码。

 

调试技巧3:利用bash的参数调试

sh [-nvx]

-n:不会执行该脚本,仅查询脚本语法是否有问题,并给出错误提示。可用于生产服务哪些只执行一次不可逆的脚本。

-v:在执行脚本时,先将脚本的内容输出到屏幕上然后执行脚本,如果有错误,也会给出错误提示。(不用)

-x:将执行的脚本内容及输出显示到屏幕上,常用。

2.2shell调试技巧小结

  1. 要记得首先用dos2unix对脚本格式化。

  2. 直接执行脚本根据报错来调试,有时报错不准确。

  3. 调试整个脚本,显示执行过程。

  4. 和set +x调试部分脚本(在脚本中设置)

  5. 输出变量及相关内容,然后紧跟着exit退出,不执行后面程序的方式,一步步跟踪脚本,对于逻辑错误比较好用。

     写法:echo $var;exit

  1. 最关键的是语法熟练、编码习惯、编程思想,将错误扼杀在萌芽之中,减轻负担,提高效率。