脚本语句

shell编程进阶

shell编程语句有循环语句,判断语句。首先来讲讲if判断语句

if语句

单分支if语句

if 判断条件 ;then
    执行条件为真的操作
fi

例:

read -p "please input number : " num    
if [ $num -gt 0 ];then
   echo "$num greater then 0"
fi   
[root@localhost ~]#./ss.sh 
please input number : 2
2 greater then 0
执行的结果是2大于0   那么就能说明判断的条件成立,所以执行后续操作。

双分支if语句

if 判断条件 ; then
    条件为真执行操作
else
    条件为假执行操作
fi   

    read -p "please input number : " num
    if  [ $num -gt 0 ] ;then
             echo "$num greater then 0"
    else
             echo "$num is not positive number or not a number"
    fi
    [root@localhost ~]#./ss.sh  
    please input number : 22
    22 greater then 0
    [root@localhost ~]#./ss.sh 
    please input number : xx
    ./ss.sh: line 9: [: xx: integer expression expected
    xx is not positive number or not a number  
事例中得出的结果可以看出,双分支的话如果条件不成立就执行else的语句

多分支if语句

      if   判断条件1; then
                  如果条件成立执行此处代码
      elif 判断条件2; then
                  如果条件成立执行此处代码
      elif 判断条件3; then
                  如果条件成立执行此处代码
          …
      else
                  如果条件都不成立执行此处代码
      fi

      read -p "please input file : " file
      if  [ -f $file ] ;then
             echo "$file is files"
      elif [ -d $file ];then
             echo "$file is derictory"
      elif [ -b $file ];then
             echo "$file is block file"
      else 
             echo "$file is other file"
      fi   
    [root@localhost ~]#./ss.sh  
    please input file : /dev/sda
    /dev/sda is block file
    [root@localhost ~]#./ss.sh  
    please input file : /root/ss.sh
    /root/ss.sh is files
    [root@localhost ~]#./ss.sh 
    please input file : /root
    /root is derictory
    [root@localhost ~]#./ss.sh 
    please input file : /dev/zero
    /dev/zero is other file
    [root@localhost ~]#
    从例子中可以看出多分支语句执行的结果是只要一条执行为真即为真

循环语句

循环语句常用的三种 for , while , until

for语句

 for 变量名      in 列表;  do 
       循环体
 done

例:

sum=0    
for i in `seq 10`;do
     let sum+=i            -->循环执行sum的值等于加i
done
echo $sum  
unset sum
unset i
[root@localhost ~]#./s.sh  
55   
例子中得出的结果是55。 当我们定义一个变量sum为0的时候去执行循环,定义i的变量从列表倒入,也就是1-10的数值,然后去执行循环体sum的值等于i的循环相加,然后得出总值55。

while语句

进入条件:当语句成立时
        循环体: 要执行的代码
退出条件:当语句不成立时

sum=0
i=0   
while [ $i -lt 11 ] ;do
       let sum+=i                  -->循环执行sum的值等于加i
       let i++                     -->当i=0的时候 let i++ 就是0+1 然后继续执行下一次循环
done
       echo $sum  
unset sum
unset i
[root@localhost ~]#./s.sh  
55
while的使用是条件成立进入循环,当条件不成立时即退出循环。

until语句

    进入条件:当语句不成立时
        循环体: 要执行的代码
    退出条件:当语句成立时

例:

sum=0
i=0   
until [ $i -eq 11 ] ;do            -->循环进入的条件,当$i等于11的时候即退出循环的条件
       let sum+=i                  -->循环执行sum的值等于加i
       let i++                     -->当i=0的时候 let i++ 就是0+1 然后继续执行下一次循环
done
       echo $sum  
unset sum
unset i
[root@localhost ~]#./s.sh  
55
循环使用的另一种风格的语法

C语言风格的语法

   #!/bin/bash
   #
   for ((sum=0,i=0;i<11;i++));do
        let sum+=i
   done
   echo $sum
   [root@localhost ~]#./s.sh  
   55
   在双小括号内的语法含义是((控制变量初始化;条件判断表达式;控制变量的修正表达式))

也可以一条命令直接算出结束,无需编写脚本。

[root@localhost ~]#for ((sum=0,i=0;i<=10;i++));do let sum+=i ;done ;echo $sum
55
select 语法
  select variable in list
  do
        循环体命令
  done

例:

脚本代码:
   #!/bin/bash
   #
   #
   PS3="please choose your menu: "                       -->PS3——Shell脚本中使用select时的提示符
   select menu in hanbao jiroujuan mianbao taocan;do
        case $REPLY in
        1)
             echo "The price is \$10"
             ;;
       2)
            echo "The price is \$15"
            ;;
       3)
            echo "The price is \$20"
            ;;
       4)
            echo "The price is \$25"
            ;;
       *)
            echo "you input food store not have "
            break
            ;;
       esac
       echo $REPLY
  done

    [root@localhost ~]#./select.sh  
    1) hanbao
    2) jiroujuan
    3) mianbao
    4) taocan
    please choose your menu: 1
    The price is $10
    1
    please choose your menu: 2
    The price is $15
    2
    please choose your menu: 3
    The price is $20
    3
    please choose your menu: 4
    The price is $25
    4
    please choose your menu: 5
    you input food store not have 
    [root@localhost ~]#

    select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示 PS3 提示符,
    等待用户输入
     用户输入菜单列表中的某个数字,执行相应的命令
     用户输入被保存在内置变量 REPLY 中
    select 是个无限循环,因此要用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c退出循环
trap捕捉信号

trap ‘触发指令’
信号自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作
trap ”
信号忽略信号的操作
trap ‘-’
信号恢复原信号的操作
trap -p
列出自定义信号
trap -l
查看所有可捕捉的信号

[root@localhost ~]#trap -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

信号详情

引用名称      默认动作          说明
SIGHUP       终止进程           终端线路挂断
SIGINT       终止进程           中断进程
SIGQUIT      建立CORE文件       终止进程,并且生成core文件
SIGILL       建立CORE文件       非法指令
SIGTRAP      建立CORE文件       跟踪自陷
SIGBUS       建立CORE文件       总线错误
SIGSEGV      建立CORE文件       段非法错误
SIGFPE       建立CORE文件       浮点异常
SIGIOT       建立CORE文件       执行I/O自陷
SIGKILL      终止进程           杀死进程
SIGPIPE      终止进程           向一个没有读进程的管道写数据
SIGALARM     终止进程           计时器到时
SIGTERM      终止进程           软件终止信号
SIGSTOP      停止进程           非终端来的停止信号
SIGTSTP      停止进程           终端来的停止信号
SIGCONT      忽略信号           继续执行一个停止的进程
SIGURG       忽略信号           I/O紧急信号
SIGIO        忽略信号           描述符上可以进行I/O
SIGCHLD      忽略信号           当子进程停止或退出时通知父进程
SIGTTOU      停止进程           后台进程写终端
SIGTTIN      停止进程           后台进程读终端
SIGXGPU      终止进程           CPU时限超时
SIGXFSZ      终止进程           文件长度过长
SIGWINCH     忽略信号           窗口大小发生变化
SIGPROF      终止进程           统计分布图用计时器到时
SIGUSR1      终止进程           用户定义信号1
SIGUSR2      终止进程           用户定义信号2
SIGVTALRM    终止进程           虚拟计时器到时

例:捕捉ctrl + c 的信号

[root@localhost ~]#vim trap.sh
  1 #!/bin/bash
  2 #
  3 #
  4 trap 'echo "ctrl + c input invalid"' int     --> 捕捉ctrl + c的信号并显示ctrl +c invalid
  5      trap -p                                 --> 列出捕捉信号的操作
  6 for ((i=0;i<10;i++));do
  7      echo $i
  8      sleep 1
  9 done
 10  
 11 trap '' int                                  -->捕捉的ctrl + c 的信号忽略
 12      trap -p
 13 for ((i=10;i<20;i++));do
 14      echo $i
 15      sleep 1
 16 done
 17 
 18 trap '-' int                                 -->捕捉的ctrl + c的信号还原
 19      trap -p
 20 for ((i=20;i<30;i++));do
 21      echo $i
 22      sleep 1
 23 done

 接下来我们运行命令然后按ctrl + c 看看捕捉到的信号是执行什么样的操作

[root@localhost ~]#./trap.sh 
trap -- 'echo "ctrl + c input invalid"' SIGINT   -->这里显示出了捕捉信号的操作内容 也就是脚本里 trap -p输出
0                                                   的内容
1
^Cctrl + c input invalid            -->当程序执行i < 10 的循环时 捕捉 ctrl + c 是无效的 捕捉到的信号打印出我
2                                      们附的值
3
^Cctrl + c input invalid
4
5
^Cctrl + c input invalid
6
7
^Cctrl + c input invalid
8
^Cctrl + c input invalid
9
trap -- '' SIGINT
10
^C11                                --> 这里捕捉到ctrl + c的信号,因为我们没写需要怎么操作,所以就直接忽略了
^C12
^C13
14
^C15
16
17
^C18
19
20                                  --> 当执行到i<30的循环时 trap '-'恢复信号trap -p不显示操作信号
21
22
23
24                                  -->当我们运行ctrl + c 的时候因为执行到了i<30的循环了,trap '-' 表示的
^C                                     是恢复原信号,所以ctrl + c 之前是中断操作 现在执行了中断
[root@localhost ~]#

例:捕捉kill的信号

[root@localhost ~]#vim trap2.sh 
1 #!/bin/bash
2 #
3 #
4 
5 trap 'echo "press input invalid"' term       -->我们定义捕捉到的kill信号直接输出进程输入无效的肉容
6     trap -p                                  -->显示下我们捕捉的信号类型
7 for ((i=0;i<100;i++));do
8     echo $i
9     sleep 1
10 done

我们运行脚本然后再开启另一台终端运行killall trap2.sh的操作,以下是具体操作内容

1终端                                                  2终端
[root@localhost ~]#./trap2.sh                         [root@localhost ~]#killall trap2.sh
trap -- 'echo "press input invalid"' SIGTERM          [root@localhost ~]#killall trap2.sh
0                                                     [root@localhost ~]#killall trap2.sh
1                                                     [root@localhost ~]#killall trap2.sh
2
3
4
5
press input invalid                                   -->当我们在2终端运行杀进程时,脚本捕捉到了killall的信
6                                                        号直接输出我们指定的内容
7
press input invalid
8
press input invalid
9
press input invalid
10
11
12
13
^C
[root@localhost ~]#

有趣事例1:使用for 循环画国际象棋棋盘

  1 #!/bin/bash
  2 #
  3 #
  4          for ((i=1;i<=16;i++)) ;do
  5               let m=$i%4
  6          case $m in
  7          1|2)
  8               for ((j=1;j<=4;j++));do
  9                  echo -ne "\033[43m    \033[0m"
 10                  echo -ne "\033[41m    \033[0m"
 11               done
 12               ;;
 13          0|3)
 14               for ((k=1;k<=4;k++));do
 15                  echo -ne "\033[41m    \033[0m"
 16                  echo -ne "\033[43m    \033[0m"
 17               done
 18               ;;
 19               esac
 20               echo
 21          done

语句的思路。首先循环i赋值,i初使值是1 循环16次。 然后为m赋值 m的值是i的值取4的模(也就是i/4取余) 然后进行case语句的使用,当m的值是 1或2的时候我们执行 j的循环,执行4次 打印4个空格的黄色和4个空格的红色 当m的值是0或3的时候 执行K的循环,执行4次 打印4个空格的红色和4个空格的黄色 。 当i的循环执行一次后用echo 进行打印一行继续执行循环,直到i的值为16为止。

运行脚本得出的结果是
这里写图片描述

有趣事例2 编写sd5后十位的数对应的数值 限 32767 范围内

[root@localhost ~]#vim mima.sh
  1 #!/bin/bash
  2 #
  3 #
  4 Var_1=efbaf275cd
  5 Var_2=4be9c40b8b
  6 Var_3=44b2395c46
  7 Var_4=f8c8873ce0
  8 Var_5=b902c16c8b
  9 Var_6=ad865d2f63
 10 for ((i=0;i<=32767;i++));do
 11     num=`echo $i |md5sum|cut -c1-10`
 12   case $num in
 13 
 14   $Var_1)
 15             echo " $Var_1=$i "
 16             ;;
 17   $Var_2)
 18             echo " $Var_6=$i "
 19             ;;
 20   $Var_3)
 21             echo " $Var_6=$i "
 22             ;;
 23   $Var_4)
 24             echo " $Var_6=$i "
 25             ;;
 26   $Var_5)
 27             echo " $Var_6=$i "
 28             ;;
 29   $Var_6)
 30             echo " $Var_6=$i "
 31   esac      
 32   
 33 done

得出的结果是

[root@localhost ~]#./mima.sh  
 ad865d2f63=1000 
 ad865d2f63=3000 
 ad865d2f63=6000 
 ad865d2f63=9000 
 ad865d2f63=12000 
 efbaf275cd=15000 

函数

函数的命名规则:列举两种常用的
  1. function name () { 函数体 }
  2. f_name () { 函数体 }
    定义本地函数变量
    1.function name () { local …}
    2.function name () { declare -i … }

    函数的定义和使用:
     可在交互式环境下定义函数
     可将函数放在脚本文件中作为它的一部分
     可放在只包含函数的单独文件中
    调用:函数只有被调用才会执行
       调用:给定函数名,函数名出现的地方,会被自动替换为函数代码
    函数的生命周期:被调用时创建,返回时终止
    

    事例:交互式定义函数

    [root@localhost ~]#seedir () {
    > ls -l
    > }
    [root@localhost ~]#seedir 
    total 39340
    -rw-r--r--. 1 root  root         0 Sep  3 14:25 11
    -rw-r--r--  1 root  root         0 Sep  3 15:17 11.aa
    -rwxr-xr-x. 1 root  root   1075246 Jul 24 10:03 access_log
    -rwx--x--x. 1 root  root      1890 Jul 15 19:51 anaconda-ks.cfg
    -rwxr-xr-x  1 root  root      1247 Sep  3 16:02 auto.sh
    -rwxr-xr-x. 1 root  root        65 Aug 18 11:56 baketc.sh
    -rwxr-xr-x  1 root  root       330 Sep  5 09:19 caidan.sh
    -rwxr-xr-x. 1 root  root       411 Aug 18 13:27 create.sh
    drwxr-xr-x. 2 root  root         6 Jul 15 19:59 Desktop
    drwxr-xr-x. 2 root  root         6 Jul 15 19:59 Documents
    [root@localhost ~]#

    事例:脚本中定义函数

  oot@CentOS6 ~]#vim func1         -->编写一个脚本
  1 #!/bin/bash
  2 #
  3 hello()                        -->定义hello的函数
  4 {
  5 echo "Hello there today's date is `date +%F`"
  6 }
  7 echo "now going to the function hello"
  8 hello                          -->调用hello的函数,调用直接输入函数名就可以
  9 echo "back from the function"
  [root@CentOS6 ~]#chmod +x func1 
  [root@CentOS6 ~]#./func1         -->执行脚本
  now going to the function hello
  Hello there today's date is 2017-09-06
  back from the function
  [root@CentOS6 ~]#

事例:脚本中定义函数的执行值

 [root@CentOS6 ~]#vim func1     
  1 #!/bin/bash
  2 #
  3 findit() 
  4 {
  5 if [ $# -lt 1 ]; then                        -->定义之前我们做下判断,脚本有输入的值,如果没有就退出并提示
  6     echo "Usage:findit file"                    下
  7     return 1
  8 fi
  9     echo "cheng gong" >/root/f1.txt
 10 }
 11 findit $1                                    -->这里的$1是下面输入的func1值
 [root@CentOS6 ~]#./func1 func1                  -->脚本后的func1是$1的值
 [root@CentOS6 ~]#cat /root/f1.txt 
 cheng gong
 [root@CentOS6 ~]#

 卸载函数:
 unset findit         跟平时取消变量一样,unset 加上函数名称就行

最后说个fork炸弹 :(){ :|:& };: 仅供参考,请勿使用,如有使用,提前做好系统备份

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值