shell脚本编程

一、编程基础:

shell脚本是包含一些命令或声明,并符合一定格式的文本文件

shell脚本的用途有:

  • 自动化常用命令

  • 执行系统管理和故障排除

  • 创建简单的应用程序

  • 处理文本或文件

1)     第一步:使用文本编辑器来创建文本文件 script.sh 并编写内容

格式要求:首行shebang    指明所要使用的shell类型

#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

结合命令、变量、表达式、语句等编写脚本内容

“#”号开头的行为注释行

#echo something
echo "test txte"

   

2)     第二步:运行脚本

给予执行权限,在命令行上指定脚本的绝对或相对路径

]#chmod +x script.sh
]#./script.sh

直接运行解释器,将脚本作为解释器程序的参数运行

]#bash script.sh

    #bash:调试执行脚本

        -n    简单检查脚本语法错误

        -x    调试执行,显示脚本运行过程

二、变量:

变量类型:

1)本地变量:作用域仅为当前shell进程

变量的定义:

    用户定义的变量有字母数字及下划线组成,

    变量名的第一个字符不能为数字.

    变量名是大小写敏感的

变量的引用:

    ${name},$name

    " ": 双引号 变量名会替换为其值
    ' ' :单引号 变量名不会替换

    查看变量:set
    撤销变量:unset name

2)环境变量:作用域为当前变量及其子进程 对其他登录用户无效

变量赋值:
   export name=value
   declare -x name=value
  
bash内嵌了很多环境变量(一般为全大写),用于定义bash工作环境

    PATH,HISTFILE,HISTSIZE,SHELL,HOME,UID,OLDPWD
    查看环境变量:export;declare -x;printenv;env
    撤销环境变量:unset name

3)局部变量:作用域为某代码片段 函数上下文

4)只读变量(常量)
  declare -r name
  readonly name
   只读变量无法重新设定,不支持撤销,当前shell终止后撤销

5)特殊变量

    $0 脚本文件路径本身 basename
    $#:参数个数
    $*:所有参数  "chen he zhao"  所有参数合并为单个字符串
    $@:所有参数  "chen" "he" "zhao" 

    位置变量:

向脚本传递位置参数变量:
  scrip.sh argu1 argu2

对应
  $1,$2…${10},${11}…
  

轮替:
   shift#   去掉前#个参数   即${#+1}变成$1

数据类型:字符型,数值型

三、数值运算:

算术运算: + – * / % ^   *乘法有时需要转义
  let var=expr
    $[expr]
    $((expr))
    $(expr argu1 argu2 argu3

 增强型赋值:
    let 
        i+=#    :i=$i+#
        i-=
        i*=
        i/=
        i%=
   自增/自减:
     let VAR=$($VAR+1)
     let VAR+=1
     let VAR++
      —

]#i=1
]#let i++
]#echo $i
]#2
]#let i+=2
]#echo $i
]#4
]#expr 3 + 4]#expr 3 \* 4]#echo 3*4|bc

四、逻辑运算:

    运算数:真(true,yes,on,1)

        假(false,no,off,0)

    1.与

        1 && 1 = 1

        1 && 0 = 0

        0 && 1 = 0

        0 && 0 = 0

    2.或

        1 || 1 = 1

        1 || 0 = 1

        0 || 1 = 1

        0 || 0 = 0

    3.非

        ! 1 = 0

        ! 0 = 1

    

    4.异或

        真真 假

        真假 真

    

    1)CMD1 && CMD2    如果真…就…

        CMD1为假 则CMD2不运行

        CMD1为真 则CMD2运行

    

    2)CMD1 || CMD2    如果假…就…

        CMD1为真 则CMD2不运行

        CMD1为假 则CMD2运行

    

五、bash测试类型:

测试表达式:

    test EXPRESSION

    [ EXPRESSION ]  表达式两端须有空格

    [[ EXPRESSION ]]

1.数值测试:  [ $num1 -## $num2 ]   整数测试!

    -eq:等于

    -ne:不等于

    -gt:大于

    -ge:大于等于

    -lt:小于

    -le:小于等于

]#[ 5 -gt 4 ]&&echo 0
]#0

2.字符串测试: [[ "CHAR" # "CHAR" ]] ASCLL码比较

    ==:是否等于

    >: 大于  ascll 编码

    <: 小于

    !=:不等于

    =~:左侧字符串 是否能够被右侧 模式匹配 

      *   -z "STRING":判断变量是否为空;空位真,不空为假

    -n "STRING":判断是否不空 空为假,不空为真

]#[[ root =~ r.*t ]]&&echo 0
]#0

3.文件测试:

 存在性测试:

    -a FILE

    -e FILE

        存在为真

 文件类型测试:[ -# /PATH/FILE ]

    -b 存在且为 块设备

    -c 存在且为 字符设备文件

    -d 存在且为 目录

    -f 存在且为 普通文件

    -p 存在且为 管道文件

    -S 存在且为 套接字文件

    -h|L  存在且为 符号链接文件

]#[ -d /etc ] && echo 0

]#0

4.文件权限测试:   以用户 实际权限;   root用户存在特权

      000  但对root可读 可写 不可执行

    -r 存在且 对当前用户可读

    -w 存在且 对当前用户可写

    -x 存在且 对对当前用户可执行

 -特殊权限测试:

    -u 存在且有 suid

    -g 存在且有 sgid

    -k 存在且有 stick

 -文件是否非空:

   * -s 不空为真,空为假

 -时间戳:

    -N 文件自最近被读后是否被修改过

 -从属关系测试:

    -O 当前用户是否 为文件属主

    -G 当前用户是否 属于文件属组

 -双目测试:mtime 判断修改时间

    FILE1 -ef FILE2 是否互为硬链接

   * FILE1 -nt FILE2 F1是否新于F2

    FILE1 -ot FILE2 F1是否旧于F2

-a = 且

-o = 或

]#a=6
]#[ $a -gt 0 -a $a -lt 9 ] && echo 0
]#0

六、脚本的状态返回值:

默认脚本执行的最后一条命令的状态返回值;

自定义状态退出状态码;

    exit [n]:     n 对应 $? 的值

     shell进程遇到exit 即结束  n=[0-255]

    利用命令状态返回值判断:

    0:成功

    1-255:失败

#read [OPTION]   获取用户输入信息,从而完成变量赋值

    -p ""设置提示信息

    -t # 设置超时时间

]#read -p "please enter a number:" num
]#please enter a number:5
]#echo $num
]#5

====作业

一、脚本

1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。

#!/bin/bash
printf %-10s "hostname:"
echo "`hostname`"
printf %-10s "ip:"
echo  "`ifconfig|sed -nr 's/.*r:(.*) B.*/\1/p'`"
printf %-10s "kernel:"
echo  "`uname -r|tr ':' ':\t'`"
printf %-10s "OS:"
echo  "OS:\t\t`cat /etc/redhat-release`"
printf %-10s "CPU:"
echo  "`lscpu|grep "Model name"|tr -d " "|cut -d: -f2`"
printf %-10s "Mem:"
echo  "free|sed -n 2p|tr -s ' '|cut -d' ' -f2"
printf %-10s "DiskSize:"
echo  "`lsblk|sed -n 2p|tr -s " "|cut -d " " -f4`"

2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中

#!/bin/bash
cp -a /etc /testdir/etc$(date +%F)&>/dev/null&&echo cp success||echo cp failuer

3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值

#!/bin/bash
echo "the max usage:`df|grep '/dev/sd.*'|tr -s ' '|cut -d' ' -f5|sort|tail -1`"

4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序

#!/bin/bash
netstat -t|tr -s ' ' ':'|cut -d: -f6|grep [0-9]|sort|uniq -c|sort -nr

5、写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和

!/bin/bash
ID1=`sed -n ${1}p /etc/passwd|cut -d: -f3`
ID2=`sed -n ${2}p /etc/passwd|cut -d: -f3`
let sum=ID1+ID2
echo "sum:$sum"

6、写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和

#!/bin/bash
blank1=`grep "^$" $1|wc -l`
blank2=`grep "^$" $2|wc -l`
let sum=blank1+blank2
echo "sum=$sum"

7、写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件

#!/bin/bash
s1=`ls /etc|wc -l`
s2=`ls /var|wc -l`
s3=`ls /usr|wc -l`
sum=$[s1+s2+s3]
echo "sum=$sum"

8、写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数

#!/bin/bash
echo -n "please enter a path:"
read path
[ ! -e $path ] &&  echo "file does not exist" && exit 5 || grep -c "^[[:space:]]*$" $path
#[[ $# -lt 1 ]] && echo "at least one arg" && exit 5 || grep -c "^[[:space:]]*$" $1

9、写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”

#!/bin/bash
read -p "please ernter a ip adddress:" addr
ping $addr -W1 -c1&>/dev/null && echo "IP address rechable!" || echo "IPaddress unrechable!"

10、判断硬盘的每个分区空间和inode的利用率是否大于80,如果是,发邮件通知root磁盘满

#!/bin/bash
disk=`df |grep "/dev/sd.*"|cut -c 44-46|sort -nr|head -1`
inode=`df -i|grep "/dev/sd.*"|cut -c 40-42|sort -nr|head -1`
[ $disk -gt 80 -o $inode -gt 80 ]&&echo 'disk fulling'|mail root||echo dont worry

11、指定文件做为参数,判断文件是否为.sh后缀,如果是,添加x权限

#!/bin/bash
[ ! -e $1 ]&&echo "file dose not exist!"&&exit 23
[[ $1 =~ .*\.sh$ ]]&&chmod +x $1&&echo '+x done'||echo not sh

12、判断输入的IP是否为合法IP

#!/bin/bash
echo -n "please enter a ip:"
read ip
echo  $ip|egrep -q "^(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>\.){3}(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>)$" && echo legal ip || echo illegal ip

13、计算1+2+3+…+100

#!/bin/bash
seq -s '+' 1 100|bc

14、输入起始值A和最后值B,计算从A+(A+1)…+(B-1)+B的总和

#!/bin/bash
seq -s '+' $1 $2|bc

原创文章,作者:Jasper,如若转载,请注明出处:http://www.178linux.com/34844

(0)
JasperJasper
上一篇 2016-08-15
下一篇 2016-08-15

相关推荐

  • liunx初探

    计算机的五大单元: 输出单元、输入单元、cpu内部控制单元、算术逻辑单元和内存。 计算机三大组成部分: 输入单元:键盘、鼠标等等 输出单元:屏幕、打印机等 中央处理器(CPU):含有算术逻辑、控制、记忆等 CPU种类有两种分别是:   精简指令集(RISC):这种cpu微指令比较精简,每个指令的执行时间都很短,完成的操作也很简单。常见的简单指令集C…

    Linux干货 2016-09-14
  • Linux发展史

    独白:    先来说说我对Linux的认识吧,用一个成语形容:狗屁不通,想了一下,文明社会还是和谐点比较好,算是闻所未闻吧。15年初从朋友那得知Linxu,冲着他那十几K的工资还是挺心动的,说实在很仰慕他,有点计算机基础,自学两个月出山,当时月薪8k;而我还是拿着3,4k的工资,也没什么本领,于是找他要了些有关视频资料,也开始了自学之路,…

    Linux干货 2017-04-08
  • Leetcode 编程训练

    Leetcode这个网站上的题都是一些经典的公司用来面试应聘者的面试题,很多人通过刷这些题来应聘一些喜欢面试算法的公司,比如:Google、微软、Facebook、Amazon之类的这些公司,基本上是应试教育的功利主义。 我做这些题目的不是为了要去应聘这些公司,而是为了锻炼一下自己的算法和编程能力。因为我开始工作的时候基本没有这样的训练算法和编程的网站,除了…

    Linux干货 2016-08-15
  • LVS模型练习

    本次涉及到的练习:nat练习、dr练习、FWM机制练习、mysql集群练习、httpd的集群练习、httpd和mysql结合调度的练习 yum install ipvsadm nat练习     设置:     (1)centos7.2作为lvs调度,有两块网卡,(公网地址)其中…

    Linux干货 2016-10-30
  • 你的数据根本不够大,别老扯什么Hadoop了

    本文原名“Don’t use Hadoop when your data isn’t that big ”,出自有着多年从业经验的数据科学家Chris Stucchio,纽约大学柯朗研究所博士后,搞过高频交易平台,当过创业公司的CTO,更习惯称自己为统计学者。对了,他现在自己创业,提供数据分析、推荐优化咨询服务,他的邮件是:stucchio@gmail.co…

    Linux干货 2015-04-04
  • 10yum源的配置

    yum仓库使用起来特别方便,然而使用之前当然是要配置的啦。下面就介绍一下怎么从0 配置一个yum仓库。 首先要创建yum仓库,当然不能使只给一台服务器用,那要给多个服务器用的话,就需要网络服务。yum仓库支持的网络服务有两种,FTP和HTTP。用yum主要用到的是数据传输,因此FTP更适合创建yum仓库,下面就以FTP为例,说明一下yum仓库的配置。 第一步…

    Linux干货 2016-11-04