设为首页 收藏本站
查看: 1065|回复: 0

shell编程总结

[复制链接]

尚未签到

发表于 2015-12-3 14:49:26 | 显示全部楼层 |阅读模式
  一、学习shell脚本之前的基础知识
  【linux shell中的特殊符号
  1. * :代表零个或多个字符或数字。
DSC0000.png
  test后面可以没有任何字符,也可以有多个字符,总之有或没有都能匹配出来。
  2. ? :只代表一个任意的字符
DSC0001.png
  不管是数字还是字母,只要是一个都能匹配出来。
  3. # :这个符号在linux中表示注释说明的意思,即”#”后面的内容linux忽略掉。
DSC0002.png
  在命令的开头或者中间插入”#” ,linux都会忽略掉的。这个符号在shell脚本中用的很多。
  4. wc :统计文档的行数、字符数、词数,常用的选项为:
  -l :统计行数
  -m :统计字符数
  -w :统计词数
DSC0003.png
  5. >, >>, 2>, 2>> :前面讲过重定向符号> 以及>> 分别表示取代和追加的意思,然后还有两个符号就是这里的2> 和2>> 分别表示错误重定向和错误追加重定向,当我们运行一个命令报错时,报错信息会输出到当前的屏幕,如果想重定向到一个文本里,则要用2>或者2>>。
DSC0004.png
  6.  [ ] :中括号,中间为字符组合,代表中间字符中的任意一个
DSC0005.png
  7. && ||
  在上面刚刚提到了分号,用于多条命令间的分隔符。另外还有两个可以用于多条命令中间的特殊符号,那就是“&&”和”||”。下面笔者把这几种情况全列出:
  1) command1 ; command2
  2) command1 && command2
  3) command1 || command2
  使用”;”时,不管command1是否执行成功都会执行command2; 使用”&&”时,只有command1执行成功后,command2才会执行,否则command2不执行;使用”||”时,command1执行成功后command2 不执行,否则去执行command2,总之command1和command2总有一条命令会执行。
DSC0006.png
  8.test测试命令
test命令用于检查某个条件是否成立,它可以进行数值、字符串和文件三个方面的测试,其测试符和相应的功能分别如下:
(1)数值测试:
        -eq:等于则为真
        -ne:不等于则为真
        -gt:大于则为真
        -ge:大于等于则为真
        -lt:小于则为真
        -le:小于等于则为真
(2)字符串测试:
        =:等于则为真
        !=:不相等则为真
        -z字符串:字符串长度伪则为真
        -n字符串:字符串长度不伪则为真
(3)文件测试:
      -e文件名:如果文件存在则为真
  -r文件名:如果文件存在且可读则为真
  -w文件名:如果文件存在且可写则为真
  -x文件名:如果文件存在且可执行则为真
  -s文件名:如果文件存在且至少有一个字符则为真
  -d文件名:如果文件存在且为目录则为真
     -f文件名:如果文件存在且为普通文件则为真
  -c文件名:如果文件存在且为字符型特殊文件则为真
  -b文件名:如果文件存在且为块特殊文件则为真
另外,Linux还提供了与(“!”)、或(“-o)、非(“-a”)三个逻辑操作符用于将测试条件连接起来,其优先级为:“!”最高,“-a”次之,“-o”最低。
同时,bash(sh不能运行)也能完成简单的算术运算,格式如下:
$[expression]
        例如:var1=2
        var2=$[var1*10+1]
        则:var2的值为21。
sh可以运行以下:
$((expression))
        例如:var1=2
        var2=$[var1*10+1]
        则:var2的值为21。
[ ] 实际上是bash 中 test 命令的简写。即所有的 [ expr ] 等于 test expr,注意  有空格。
9. (())
  使用方法:
  语法:
  ((表达式1,表达式2…))
  特点:
  1、在双括号结构中,所有表达式可以像c语言一样,如:a++,b--等。
  2、在双括号结构中,所有变量可以不加入:“$”符号前缀。
  3、双括号可以进行逻辑运算,四则运算
  4、双括号结构 扩展了for,while,if条件测试运算
  5、支持多个表达式运算,各个表达式之间用“,”分开
  使用实例:

  • 扩展四则运算



1
2
3
4
5
6
7
8
9
10
11


#!/bin/sh

a=1;
b=2;
c=3;

((a=a+1));
echo $a;

a=$((a+1,b++,c++));
echo $a,$b,$c
  
  运行结果:
  sh testsh.sh
2
3,3,4
  双括号结构之间支持多个表达式,然后加减乘除等c语言常用运算符都支持。如果双括号带:$,将获得表达式值,赋值给左边变量。


  • 扩展逻辑运算



1
2
3
4
5
6
7
8
9
10


#!/bin/sh

a=1;
b="ab";


echo $((a>1?8:9));

((b!="a"))&& echo "err2";
((a<2))&& echo "ok";
  
  运行结果:
  sh testsh.sh
9
err2
ok


  • 扩展流程控制语句(逻辑关系式)



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22


#!/bin/sh

num=100;
total=0;

for((i=0;i<=num;i++));
do
    ((total+=i));
done
echo $total;

total=0;
i=0;
while((i<=num));
do
    ((total+=i,i++));
done
echo $total;

if((total>=5050));then
    echo "ok";
fi
  
  运算结果:
  sh testsh.sh
5050
5050
ok
  
  有了双括号运算符:[[]],[],test 逻辑运算,已经let,expr 都可以抛到一边了。
  二、SHELL 脚本
  有一个问题需要约定一下,凡是自定义的脚本建议放到/usr/local/sbin/目录下,这样做的目的是,一来可以更好的管理文档;二来以后接管你的管理员都知道自定义脚本放在哪里,方便维护。
  
  【shell脚本的基本结构以及如何执行
  
DSC0007.png
  
  Shell脚本通常都是以.sh 为后缀名的,这个并不是说不带.sh这个脚本就不能执行,只是大家的一个习惯而已。所以,以后你发现了.sh为后缀的文件那么它一定会是一个shell脚本了。test.sh中第一行一定是 “#! /bin/bash” 它代表的意思是,该文件使用的是bash语法。如果不设置该行,那么你的shell脚本就不能被执行。’#’表示注释,在前面讲过的。后面跟一些该脚本的相关注释内容以及作者和创建日期或者版本等等。当然这些注释并非必须的,如果你懒的很,可以省略掉,但是笔者不建议省略。因为随着你工作时间的增加,你写的shell脚本也会越来越多,如果有一天你回头查看你写的某个脚本时,很有可能忘记该脚本是用来干什么的以及什么时候写的。所以写上注释是有必要的。另外系统管理员并非你一个,如果是其他管理员查看你的脚本,他看不懂岂不是很郁闷。该脚本再往下面则为要运行的命令了。
DSC0008.png
  Shell脚本的执行很简单,直接”sh filename “ 即可,另外你还可以这样执行
DSC0009.png
  默认我们用vim编辑的文档是不带有执行权限的,所以需要加一个执行权限,那样就可以直接使用’./filename’ 执行这个脚本了。另外使用sh命令去执行一个shell脚本的时候是可以加-x选项来查看这个脚本执行过程的,这样有利于我们调试这个脚本哪里出了问题。
DSC00010.png
  该shell脚本中用到了’date’这个命令,它的作用就是用来打印当前系统的时间。其实在shell脚本中date使用率非常高。有几个选项笔者常常在shell脚本中用到:
DSC00011.png
  %Y表示年,%m表示月,%d表示日期,%H表示小时,%M表示分钟,%S表示秒
DSC00012.png
  注意%y和%Y的区别。
DSC00013.png
  -d 选项也是经常要用到的,它可以打印n天前或者n天后的日期,当然也可以打印n个月/年前或者后的日期。
DSC00014.png
  另外星期几也是常用的
DSC00015.png
  【shell脚本中的变量
  在shell脚本中使用变量显得我们的脚本更加专业更像是一门语言,开个玩笑,变量的作用当然不是为了专业。如果你写了一个长达1000行的shell脚本,并且脚本中出现了某一个命令或者路径几百次。突然你觉得路径不对想换一下,那岂不是要更改几百次?你固然可以使用批量替换的命令,但是也是很麻烦,并且脚本显得臃肿了很多。变量的作用就是用来解决这个问题的。
DSC00016.png
  在test2.sh中使用到了反引号,你是否还记得它的作用?’d’和’d1’在脚本中作为变量出现,定义变量的格式为 “变量名=变量的值”。当在脚本中引用变量时需要加上’$’符号,这跟前面讲的在shell中自定义变量是一致的。下面看看脚本执行结果吧。
DSC00017.png
  下面我们用shell计算两个数的和。
DSC00018.png
  数学计算要用’[ ]’括起来并且外头要带一个’$’。脚本结果为:
DSC00019.png
  Shell脚本还可以和用户交互。
DSC00020.png
  这就用到了read命令了,它可以从标准输入获得变量的值,后跟变量名。”read x”表示x变量的值需要用户通过键盘输入得到。脚本执行过程如下:
DSC00021.png
  我们不妨加上-x选项再来看看这个执行过程:
DSC00022.png
  在test4.sh中还有更加简洁的方式。
DSC00023.png
  read -p 选项类似echo的作用。执行如下:
DSC00024.png
  你有没有用过这样的命令”/etc/init.d/iptables restart “ 前面的/etc/init.d/iptables 文件其实就是一个shell脚本,为什么后面可以跟一个”restart”? 这里就涉及到了shell脚本的预设变量。实际上,shell脚本在执行的时候后边是可以跟变量的,而且还可以跟多个。不妨笔者写一个脚本,你就会明白了。
DSC00025.png
  执行过程如下:
DSC00026.png
  在脚本中,你会不会奇怪,哪里来的$1和$2,这其实就是shell脚本的预设变量,其中$1的值就是在执行的时候输入的1,而$2的值就是执行的时候输入的$2,当然一个shell脚本的预设变量是没有限制的,这回你明白了吧。另外还有一个$0,不过它代表的是脚本本身的名字。不妨把脚本修改一下。
DSC00027.png
  执行结果想必你也猜到了吧。
DSC00028.png
  var="Hello"  #
var=Hello
var='Hello'   #将忽略$等
  以上变量赋值等价,
  注意几点:
  1.变量和值之间不能有空格,否则解释器会认为是几个命令。很多程序员的习惯是在=号两边留空格为了好看,但这点在shell中行不通。
  2.字符串不必用"号或者',上面的几种赋值方式是等价的。除非字符串之间有空格或有变量的时候。
  如:var="Hello World"
  var="$a$b"
  【shell脚本中的逻辑判断
  如果你学过C或者其他语言,相信你不会对if 陌生,在shell脚本中我们同样可以使用if逻辑判断。在shell中if判断的基本语法为:
  1)不带else
  if 判断语句; then
  command
  fi
DSC00029.png
  在if1.sh中出现了 ((a<60))这样的形式,这是shell脚本中特有的格式,用一个小括号或者不用都会报错,请记住这个格式,即可。执行结果为:
DSC00030.png
  )带有else
  if 判断语句 ; then
  command
  else
  command
  fi
DSC00031.png
  执行结果为:
DSC00032.png
  3)带有elif
  if 判断语句一 ; then
  command
  elif 判断语句二; then
  command
  else
  command
  fi
DSC00033.png
  这里的 && 表示“并且”的意思,当然你也可以使用 || 表示“或者”,执行结果:
DSC00034.png
  以上只是简单的介绍了if语句的结构。在判断数值大小除了可以用”(( ))”的形式外,还可以使用”[ ]”。但是就不能使用>, < , = 这样的符号了,要使用 -lt (小于),-gt (大于),-le (小于等于),-ge (大于等于),-eq (等于),-ne (不等于)。
DSC00035.png
  再看看if中使用 && 和 ||的情况。
DSC00036.png
  shell 脚本中if还经常判断关于档案属性,比如判断是普通文件还是目录,判断文件是否有读写执行权限等。常用的也就几个选项:
  -e :判断文件或目录是否存在
  -d :判断是不是目录,并是否存在
  -f :判断是否是普通文件,并存在
  -r :判断文档是否有读权限
  -w :判断是否有写权限
  -x :判断是否可执行
  使用if判断时,具体格式为: if [ -e filename ] ; then
DSC00037.png
  在shell 脚本中,除了用if来判断逻辑外,还有一种常用的方式,那就是case了。具体格式为:
  case 变量 in
  value1)
  command
  ;;
  value2)
  command
  ;;
  value3)
  command
  ;;
  *)
  command
  ;;
  esac
  上面的结构中,不限制value的个数,*则代表除了上面的value外的其他值。下面笔者写一个判断输入数值是奇数或者偶数的脚本。
DSC00038.png
  $a 的值或为1或为0,执行结果为:
DSC00039.png
  也可以看一下执行过程:
DSC00040.png
  case脚本常用于编写系统服务的启动脚本,例如/etc/init.d/iptables中就用到了,你不妨去查看一下。
  【shell脚本中的循环
  Shell脚本中也算是一门简易的编程语言了,当然循环是不能缺少的。常用到的循环有for循环和while循环。下面就分别介绍一下两种循环的结构。do开始,done结束。
DSC00041.png
  脚本中的seq 1 5 表示从1到5的一个序列。你可以直接运行这个命令试下。脚本执行结果为:
DSC00042.png
  通过这个脚本就可以看到for循环的基本结构 :
  for 变量名 in 循环的条件; do
  command
  done
DSC00043.png
  循环的条件那一部分也可以写成这样的形式,中间用空格隔开即可。你也可以试试,for i in `ls`; do echo $i; done 和 for i in `cat test.txt`; do echo $i; done
DSC00044.png
  再来看看这个while循环,基本格式为:
  while 条件; do
  command
  done
  脚本的执行结果为:
DSC00045.png
  另外你可以把循环条件忽略掉,笔者常常这样写监控脚本。
  while :; do
  command
  done
  【shell脚本中的函数
  如果你学过开发,肯定知道函数的作用。如果你是刚刚接触到这个概念的话,也没有关系,其实很好理解的。函数就是把一段代码整理到了一个小单元中,并给这个小单元起一个名字,当用到这段代码时直接调用这个小单元的名字即可。有时候脚本中的某段代总是重复使用,如果写成函数,每次用到时直接用函数名代替即可,这样就节省了时间还节省了空间。
DSC00046.png
  fun.sh 中的sum() 为自定义的函数,在shell脚本中要用
  function 函数名() {
  command
  }
  这样的格式去定义函数。
  上个脚本执行过程如下:
DSC00047.png
  有一点笔者要提醒你一下,在shell脚本中,函数一定要写在最前面,不能出现在中间或者最后,因为函数是要被调用的,如果还没有出现就被调用,肯定是会出错的。
  Shell脚本大体上就介绍这么多了,笔者所举的例子都是最基础的,所以即使你把所有例子完全掌握也不代表你的shell脚本编写能力有多么好。所以剩下的日子里你尽量要多练习,多写脚本,你写的脚本越多,你的能力就越强。希望你能够找专门介绍shell脚本的书籍深入的去研究一下它。随后笔者将给你留几个shell脚本的练习题,你最好不要偷懒。
  1. 编写shell脚本,计算1-100的和;
  2. 编写shell脚本,要求输入一个数字,然后计算出从1到输入数字的和,要求,如果输入的数字小于1,则重新输入,直到输入正确的数字为止;
  3. 编写shell脚本,把/root/目录下的所有目录(只需要一级)拷贝到/tmp/目录下;
  4. 编写shell脚本,批量建立用户user_00, user_01, … ,user_100并且所有用户同属于users组;
  5. 编写shell脚本,截取文件test.log中包含关键词’abc’的行中的第一列(假设分隔符为”:”),然后把截取的数字排序(假设第一列为数字),然后打印出重复次数超过10次的列;
  6. 编写shell脚本,判断输入的IP是否正确(IP的规则是,n1.n2.n3.n4,其中1<n1<255, 0<n2<255, 0<n3<255, 0<n4<255)。
  以下为练习题答案:
  1. #! /bin/bash
  sum=0
  for i in `seq 1 100`; do
  sum=$[$i+$sum]
  done
  echo $sum
  2. #! /bin/bash
  n=0
  while [ $n -lt "1" ]; do
  read -p "Please input a number, it must greater than "1":" n
  done
  
  sum=0
  for i in `seq 1 $n`; do
  sum=$[$i+$sum]
  done
  echo $sum
  
  3. #! /bin/bash
  for f in `ls /root/`; do
  if [ -d $f ] ; then
  cp -r $f /tmp/
  fi
  done
  
  4. #! /bin/bash
  groupadd users
  for i in `seq 0 9`; do
  useradd -g users user_0$i
  done
  
  for j in `seq 10 100`; do
  useradd -g users user_$j
  done
  
  5. #! /bin/bash
  awk -F':' '$0~/abc/ {print $1}' test.log >/tmp/n.txt
  sort -n n.txt |uniq -c |sort -n >/tmp/n2.txt
  awk '$1>10 {print $2}' /tmp/n2.txt
  
  6. #! /bin/bash
  checkip() {
  if echo $1 |egrep -q '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' ; then
  a=`echo $1 | awk -F. '{print $1}'`
  b=`echo $1 | awk -F. '{print $2}'`
  c=`echo $1 | awk -F. '{print $3}'`
  d=`echo $1 | awk -F. '{print $4}'`
  
  for n in $a $b $c $d; do
  if [ $n -ge 255 ] || [ $n -le 0 ]; then
  echo "the number of the IP should less than 255 and greate than 0"
  return 2
  fi
  done
  else
  echo "The IP you input is something wrong, the format is like 192.168.100.1"
  return 1
  fi
  }
  
  rs=1
  while [ $rs -gt 0 ]; do
  read -p "Please input the ip:" ip
  checkip $ip
  rs=`echo $?`
  done
  echo "The IP is right!"
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-146902-1-1.html 上篇帖子: 【程序员技术练级】熟悉Unix/Linux Shell和常见的命令行(一)文件系统结构和基本操作 下篇帖子: Shell 常用命令总结
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表