[关闭]
@Great-Chinese 2017-03-17T08:44:59.000000Z 字数 5910 阅读 848

Shell编程进阶

Shell编程进阶


1.1 shell结构以及执行

  1. mkdir shell
  2. cd shell/
  3. # 编辑脚本文件
  4. vim first.sh # 增加内容如下
  5. #!/bin/bash
  6. ##The first test shell script.
  7. ##Written by melody.
  8. ls /tmp/
  9. echo "This is the first script."
  10. # 执行脚本方法
  11. bash first.sh # bash直接接文件名
  12. chmod a+x first.sh # 增加x权限,然后直接相对路径执行
  13. ./first.sh
  14. /root/shell/first.sh # 用绝对路径执行
  15. ls -l /bin/bash
  16. ls -l /bin/sh
  17. sh first.sh # 也可以有sh执行
  18. sh -x first.sh # 查看脚本的执行过程,方便排错

1.2 date命令

  1. date # 查看系统日期
  2. cal # 查看当月日历
  3. cal -y # 查看整年的日历
  4. date -s "2016-12-8 11:08" # 修改系统时间
  5. yum install -y ntp # 安装ntp
  6. ntpdate time.windows.com # 同步windows时间
  7. ntpdate ntp.fudan.edu.cn # 同步fudan时间
  8. date +%F # 显示年-月-日
  9. date +%T # 显示时:分:秒
  10. date +%Y # 显示年(2016)
  11. date +%y # 显示年(16)
  12. date +%m # 显示月
  13. date +%d # 显示日
  14. date +%H # 显示时
  15. date +%M # 显示分
  16. date +%S # 显示秒
  17. date +%s # 时间圈(距离1970-1-1 0:0:0到现在走了多少秒)
  18. date +%w # 显示星期几
  19. date +%W # 显示一年内的第几个星期
  20. date +"%Y-%m-%d %H:%M:%S" # 显示年-月-日 时:分:秒
  21. date -d "-2 days" +%F # 显示两天前的年-月-日
  22. date -d "-2 month" +%F # 显示两个月前的年-月-日
  23. date -d "-2 hour" +%T # 显示2小时前的时:分:秒
  24. date -d "-2 min" +%T # 显示2分钟前的时:分:秒
  25. date -d "-200 sec" +%T # 显示200秒前的时:分:秒

1.3 shell自定义变量

1,用户交互的脚本

  1. # 编辑与用户交互的脚本
  2. vim 2.sh # 增加内容如下
  3. #!/bin/bash
  4. ##The first test shell script.
  5. ##Written by melody.
  6. read -t 3 -p "Please input a number:" number (-t: 3秒之后,会自动退出)
  7. echo $number
  8. # 执行脚本
  9. sh 2.sh
  10. Please input a number:1 # 输入什么打印什么
  11. 1

2,内指脚本 ???????????????????????????????????????????????????????????????????

  1. # 编辑内指脚本
  2. vim 3.sh # 增加内容如下
  3. #!/bin/bash
  4. ##The first test shell script.
  5. ##Written by melody.
  6. echo "\$1= $1"
  7. echo "\$2= $2"
  8. echo "\$3= $3"
  9. echo "\$0= $0"
  10. # 执行内指脚本
  11. sh 3.sh aa bb cc # 显示内容如下
  12. $1= aa
  13. $2= bb
  14. $3= cc
  15. $0= 3.sh

3,数学运算

  1. # 数学运算
  2. a=1;b=2
  3. c=$[$a+$b]
  4. echo $c

1.4 if逻辑判断

大于:-gt 小于:-lt 等于:-eq 不等于:-ne 大于等于:-ge 小于等于:-le

1, 简单格式

  1. vim if.sh # 增加内容如下:
  2. #!/bin/bash
  3. a=5
  4. if [ $a -gt 3 ]
  5. then
  6. echo "a>3"
  7. fi
  8. # 执行if脚本
  9. sh -x if.sh

2,多条件的if格式

  1. #!/bin/bash
  2. a=5
  3. if [ $a -gt 10 ]
  4. then
  5. echo "a>10"
  6. else
  7. echo "a<=10"
  8. fi
  9. # 执行if脚本
  10. sh -x if.sh

3,多条件的if格式

  1. #!/bin/bash
  2. a=5
  3. if [ $a -gt 10 ]
  4. then
  5. echo "a>10"
  6. elif [ $a -lt 4 ]
  7. then
  8. echo "a<4"
  9. else
  10. echo "4<a<10"
  11. fi
  12. # 执行if脚本
  13. sh -x if.sh

1.5 if判断的几种用法

1,判断变量是否不为空 -n,反引号表示把一个命令的结果赋值给m,即一个变量

  1. vim if2.sh # 增加内容如下
  2. #!/bin/bash
  3. read -p "Please input a number: " n # 输入一串字符 赋值$n
  4. m=`echo $n|sed 's/[0-9]//g'` #
  5. if [ -n "$m" ] # 如果变量$m不是空格 ?????????????????????????
  6. then
  7. echo "The character you input is not a number, please retry." # 则输出此行
  8. else
  9. echo $n # 否则输出$n
  10. fi
  11. # 执行if脚本
  12. sh if2.sh

2,判断变量是否为空 -z,反引号表示把一个命令的结果赋值给m,即一个变量

  1. vim if2.sh # 增加内容如下
  2. #!/bin/bash
  3. read -p "Please input a number: " n # 输入一串字符 赋值$n
  4. m=`echo $n|sed 's/[0-9]//g'` #
  5. if [ -z "$m" ] # 如果变量$m是空格
  6. then
  7. echo $n # 则输出$n
  8. else
  9. echo "The character you input is not a number, please retry." # 否则输出此行
  10. fi
  11. # 执行if脚本
  12. sh if2.sh

3,针对文件和目录的逻辑判断

  1. grep '^melody' /etc/passwd
  2. grep '^gary' /etc/passwd
  3. # -q 作为判断条件
  4. if grep -q '^gary' /etc/passwd; then echo "gary exist"; fi
  5. if [ -d /tmp/ ] && [ -f 1.txt ]; then echo ok; fi # 并且
  6. if [ -d /tmp/ ] || [ -f 2.txt ]; then echo ok; fi # 或者
  7. if [ -d /tmp/ -a -f 1.txt ]; then echo ok; fi # -a 并且
  8. if [ -d /tmp/ -o -f 1.txt ]; then echo ok; fi # -o 或者

1.6 case选择(逻辑判断的一种格式,在启动脚本中用的比较多)

1,判断奇偶数

  1. vim case.sh # 增加内容如下
  2. #!/bin/bash
  3. read -p "Please input a number:" n # 输入一串字符 赋值$n
  4. m=$[$n%2] # 变量=$n除以2
  5. echo $m # 判断变量$m
  6. case $m in
  7. 1) # 等于1
  8. echo "The number is jishu." # 输出这是个奇数
  9. ;;
  10. 0) # 等于0
  11. echo "The number is oushu." # 输出这是个偶数
  12. ;;
  13. *) # 等于其他
  14. echo "It is not jishu or oushu." # 输出这不是奇数和偶数
  15. ;;
  16. esac
  17. # 执行case脚本 (一个字符串的值,默认为0)
  18. sh case.sh
  19. Please input a number:222
  20. The number is oushu.

1.7 for循环

1,序列命令

  1. # 产生序列的命令
  2. seq 1 10
  3. 1 2 3 4 5 6 7 8 9 10
  4. # 从1开始增加2显示这个数字,到8结束
  5. seq 1 2 8
  6. 1 3 5 7
  7. # 从8开始减除2显示这个数字,到1结束
  8. seq 8 -2 1
  9. 8 6 4 2
  10. # 从8开始减除1显示这个数字,到1结束
  11. seq 8 -1 1
  12. 8 7 6 5 4 3 2 1
  13. # 按最宽的长度生成序列格式 -w
  14. seq -w 1 10
  15. seq -w 1 100

2,循环1,10 (两种格式一样的效果)

  1. vim for.sh # 增加内容如下,格式1
  2. #!/bin/bash
  3. for i in `seq 1 10`
  4. do
  5. echo $i
  6. done
  7. # 执行for脚本
  8. sh for.sh
  1. vim for.sh # 增加内容如下,格式2
  2. #!/bin/bash
  3. for i in {1..10}
  4. do
  5. echo $i
  6. done
  7. # 执行for脚本
  8. sh for.sh

3,数字求和

  1. vim for.sh # 增加内容如下
  2. #!/bin/bash
  3. sum=0
  4. for i in {1..10}
  5. do
  6. sum=$[$sum+$i]
  7. done
  8. echo $sum
  9. # 执行for脚本
  10. sh for.sh
  11. 55

4,循环文件的内容

  1. vim 2.txt # 编辑文件内容如下
  2. 1 2
  3. jfdklsdl
  4. aa bb
  5. # for循环
  6. for l in `cat 2.txt`; do echo $l; done # 显示循环的文件内容
  7. 1
  8. 2
  9. jfdklsdl
  10. aa
  11. bb

5,循环ip

  1. vim 3.txt # 编辑ip列表内容如下
  2. 1.1.1.1
  3. 2.2.2.2
  4. 3.3.3.3
  5. # for循环
  6. for ip in `cat 3.txt`; do echo $ip; done # 根据ip做为循环的对象
  7. for ip in `cat 3.txt`; do echo $ip;ssh $ip "w"; done # 改成自己的服务器ip,即可形成自动化运帷脚本

6,循环当前目录的名称

  1. for file in `ls`; do echo $file; done # 循环当前目录下的每个名称内容
  2. for file in `ls`; do echo $file;du -sh $file; done # 循环当前目录下的每个名称内容并显示大小

1.8 while循环 -用于死循环,作为监控脚本

1,死循环

  1. vim while.sh # 增加内容如下
  2. #!/bin/bash
  3. while :
  4. do
  5. date +%T
  6. sleep 3
  7. done
  8. # 执行死循环
  9. sh while.sh # 查看时间,3秒循环1次

2,打印1-10

  1. vim while1.sh # 增加内容如下
  2. #!/bin/bash
  3. n=1
  4. while [ $n -le 10 ]
  5. do
  6. echo $n
  7. n=$[$n+1]
  8. done
  9. # 执行打印循环
  10. sh while1.sh

3,交互循环
不用if判断,如果输入的不是数字将一直进行,直到输入的是数字后,才会自动退出

  1. vim while2.sh # 增加内容如下
  2. #!/bin/bash
  3. n=1
  4. while [ ! -z "$n" ] ?????????????????????????????
  5. do
  6. read -p "Please input a number:" m
  7. n=`echo $m |sed 's/[0-9]//g'`
  8. echo $m
  9. done
  10. # 执行交互循环
  11. sh while2.sh # 如果输入的不是数字将一直进行,直到输入的是数字后,才会自动退出

1.9 shell中断继续退出

break 是中断该层循环。 exit是直接退出脚本。 这个shift的意思是把第二个参数变为第一个参数,第一个参数删除

1, break 中断(结束整个for循环)

  1. vim for3.sh # 增加内容如下
  2. #!/bin/bash
  3. for i in `seq 1 3`
  4. do
  5. echo $i
  6. if [ $i -eq 2 ]
  7. then
  8. break
  9. fi
  10. echo $i
  11. done
  12. echo "for done"
  13. # 执行for循环
  14. sh for3.sh # 打印结果如下
  15. 1
  16. 1
  17. 2
  18. for done

2,continue 继续 (结束本次shell脚本的循环) ???????????????????????????

  1. vim for3.sh # 增加内容如下
  2. #!/bin/bash
  3. for i in `seq 1 5`
  4. do
  5. echo $i
  6. if [ $i -eq 3 ]
  7. then
  8. continue
  9. fi
  10. echo $i
  11. done
  12. echo "for done"
  13. # 执行for循环
  14. sh for3.sh # 打印结果如下
  15. 1
  16. 1
  17. 2
  18. 3
  19. 3
  20. for done

3,exit 退出 (直接结束整个shell脚本,后面的命令都不用执行) ??????????????

  1. #!/bin/bash
  2. for i in `seq 1 5`
  3. do
  4. echo $i
  5. if [ $i -eq 3 ]
  6. then
  7. exit
  8. fi
  9. echo $i
  10. done
  11. echo "for done"
  12. # 执行for循环
  13. sh for3.sh # 打印结果如下
  14. 1
  15. 1
  16. 2

2.0 shell函数 ???????????????????

1,函数

  1. vim fun.sh # 编辑函数,增加内容如下
  2. #!/bin/bash
  3. function mysum() { # function 可以省略不写
  4. sum=$[$1+$2]
  5. echo $sum
  6. }
  7. a=1
  8. b=2
  9. mysum $a $b
  10. # 执行函数
  11. sh fun.sh # 打印结果
  12. 3

2,引用函数里面的变量

  1. vim fun.sh # 编辑函数,增加内容如下
  2. #!/bin/bash
  3. function mysum() {
  4. sum=$[$1+$2]
  5. echo $sum
  6. }
  7. a=1
  8. b=2
  9. mysum $a $b
  10. echo $sum
  11. # 执行函数
  12. sh fun.sh # 打印结果
  13. 3
  14. 3

3,让函数里的变量只在函数里使用

  1. vim fun.sh # 编辑函数,增加内容如下
  2. #!/bin/bash
  3. function mysum() {
  4. local sum=$[$1+$2] # local表示只在子函数中生效
  5. echo $sum
  6. }
  7. a=1
  8. b=2
  9. mysum $a $b
  10. echo $sum
  11. # 执行函数
  12. sh fun.sh # 打印结果
  13. 3

2.1 shell数组 ???????????????????

1,数组的定义

  1. a=(1 2 3 4) # 定义一个数组
  2. echo ${a[@]} # 显示一个数组 @
  3. 1 2 3 4
  4. echo ${a[*]} # 显示一个数组 *
  5. 1 2 3 4
  6. echo ${a[0]} # 显示数组中的第一个元素
  7. 1
  8. echo ${a[1]} # 显示数组中的第一个元素
  9. 2
  10. a[4]=8 # 增加数组元素
  11. echo ${a[*]} # 显示增加数组元素后的数组
  12. 1 2 3 4 8
  13. a[1]=6 # 更改数组中的某个元素
  14. echo ${a[*]} # 显示更改数组中的某个元素后的数组
  15. 1 6 3 4 8
  16. echo ${#a[*]} # 获得数组的元素总个数
  17. 5

2,数组排序

  1. # 选取10个随机数,即赋值
  2. for i in `seq 0 9`; do a[$i]=$RANDOM; done; echo ${a[@]}
  3. 13476 495 11510 27164 28450 18206 7545 9094 19343 12099
  4. # 比较随机数的大小,即排序
  5. for i in `seq 0 9`; do a[$i]=$RANDOM; done; echo ${a[@]} |sed 's/ /\n/g'|sort -n
  6. 164
  7. 9350
  8. 13657
  9. 15794
  10. 17788
  11. 22975
  12. 26047
  13. 28816
  14. 30240
  15. 30956
  16. # 删除数组
  17. unset a
  18. echo ${a[@]} # 删除数组后,数组值将为空

3,

  1. # 选取10个随机数,即重新赋值
  2. for i in `seq 0 9`; do a[$i]=$RANDOM; done; echo ${a[@]}
  3. 19206 1570 20842 11823 5848 31177 14322 2679 11957 3307
  4. # 删除数组的第5个元素
  5. unset a[4]
  6. echo ${a[@]} # 显示删除数组第5个元素后的数组
  7. 19206 1570 20842 11823 31177 14322 2679 11957 3307
  8. # 重新赋值
  9. for i in `seq 0 9`; do a[$i]=$RANDOM; done; echo ${a[@]}
  10. 19349 12146 31114 2462 1238 5914 25162 32432 32167 2394
  11. # 按顺序选取指定第几个元素
  12. echo ${a[@]:0:4}
  13. 19349 12146 31114 2462
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注