Shell脚本

来源:互联网 发布:放大电路 知乎 编辑:程序博客网 时间:2024/06/05 21:18

说明:$符号不能正常显示的地方使用¥代替
1、命名、编写、执行
脚本的名字以.sh作为结尾,比如test.sh
脚本中第一行指定shell的版本,通常使用标准shell,即#!/bin/bash
脚本中使用#为脚本添加注释
脚本编写完成后,使用chmod 755 scriptname命令,赋予执行权限
使用./scriptname parameter1 parameter2… 或sh scriptname parameter1 parameter2 执行脚本
2、常用命令
read命令
作用: 接收键盘输入,与脚本进行交互
格式:read 选项 变量名
选项
-p 输出提示信息
-t 指定等待时间(秒),默认会一直等待用户输入
-n 指定接收的字符数
-s 隐藏输入的数据
eg
read -p “please input your name” -t 10 name 将用户输入的值赋予name

echo命令
echo 字符串 输出字符串或变量的值,默认输出后会换行,且不会识别特殊字符
echo -n 字符串 输出字符串或变量的值,不换行
echo -e 字符串 输出字符串或变量的值,在遇到 特殊字符时需转换,比如\n代表换行
3、常用符号及变量

符号 描述 ’ ‘ 单引号 在单引号中所有特殊符号均无特殊含义 ” “ 双引号 在双引号中,除“$”“\”外其他特殊符号都无特殊含义 $( ) 括号中使用系统命令 $ 调用变量的值 \ 反斜杠 转义符,转义符的特殊字符无特殊含义 ¥n 代表命令行的第n个参数,$0代表命令本身 $# 代表命令行中参数的个数 $* 代表命令行中所有参数,把所有参数看成一个整体 $@ 代表命令行中所有参数,把每个参数区别对待 $? 代表最后一次执行的命令的返回状态,返回变量值为0代表执行成功,否则不成功 $$ 代表当前进程的进程号 $! 代表后台运行的最后一个进程的进程号

4、变量分类
●用户自定义变量。
局部变量,只对当前shell生效
定义 :变量名=变量值 变量名必须以字母或下划线开头,由字母、数字或下划线当变量中含有空格时,需要使用双引号或单引号将变量括起来,变量默认为字符串类型
声明 :declare [+/-] [选项] 变量名
选项: +取消变量属性 -设置变量属性 -i 设置为整型 -a 设置为数组 -r 只读变量

定义数组: arr_name=(value1 value2 ….)或 使用arr_name[index]=value单独为元素赋值
注意:
数组元素放在小括号内,而不是大括号,元素之间使用空格分开,而不是逗号,元素下标从0开始

获取数组元素: {arr_name[index]} 索引号为index的元素 {array_name[*]}数组的所有元素
获取数组长度: {#arr_name[*]}

数值运算:¥(()) 例如: a=1 b=2 c=¥((¥a+¥b))
●环境变量。
全局变量,对子shell(使用bash进入子shell,使用exit退出子shell)同样生效,需要大写
查看环境变量 : env
设置环境变量:声明新的变量:export 变量名=变量值;将之前变量声明为全局变量: export 变量名
删除环境变量:unset 变量名 (在父shell中定义的环境变量,只能在父shell中删除)
●预定义变量
Bash已经定义好的变量,变量名无法修改,具有固定的作用,比如:¥n、¥*、¥#
5、函数
定义

function function_name{action}

action由shell命令组成,定义中没有参数,可以使用return返回返回值,如果不使用return则默认返回值为最后一条命令执行的结果,同一行中如果有多条命令,则使用分号分开,最好一行只写一条命令。
调用
functionname varname1 varname2….. 函数名后边的参数可以使用¥n进行引用
eg

#!/bin/bashfunction test{echo "$1"echo "$2"}test "hello"  "world"

6、条件判断
使用[]可以对条件进行测试,使用[[ ]]可以对多个条件进行判断
eg

[[ -e /root/install.log&&-e /root/install.log.syslog ]]

●按文件类型判断
-e 判断文件是否存在,存在则返回真
-d 判断文件是否存在,并且是否为目录,是则返回真
-f 判断文件是否存在,并且是否为普通文件,是则返回真
格式:[选项 文件]
eg
[-e /root/install.log] 文件存在命令成功执行,返回真
[-e /root/install.log]&&echo “yes”|| echo “no” 如果存在文件则输出yes,否则输出

●按文件权限判断
-r 判断文件是否存在,并且是否拥有读权限,有则返回真
-w 判断文件是否存在,并且是否拥有写权限,有则返回真
-x 判断文件是否存在,并且是否拥有执行权限,有则返回真
格式:[选项 文件]
eg
[-r /root/install.log] 判断文件是否拥有读权限,有则返回真0

●两个文件比较
文件1 -nt 文件2 判断文件1是否比文件2新
文件1 -ot 文件2 判断文件1是否比文件2旧
文件1 -ef 文件2 判断文件1和文件2的i节点是否相同,即是否是同一个文件,是否是硬链接
eg
[newfile -nt oldfile] 返回真

●整数比较
整数1 -eq 整数2 判断是否相等
整数1 -ne 整数2 判断是否不等
整数1 -gt 整数2 判断整数1是否大于整数2
整数1 -lt 整数2 判断整数1是否小于整数2
整数1 -ge 整数2 判断整数1是否大于等于整数2
整数1 -le 整数2 判断整数1是否小于等于整数2
在进行比较时,shell会自动将数据类型转换为数值型
eg
[1 -ge 2]&&echo “yes”|| echo “no” 输出no

●字符串判断
-z 判断字符串是否为空
-n 判断字符串是否不为空
字符串1==字符串2 判断字符串是否相等
字符串1!=字符串2 判断字符串是否不等
eg

a=""   [-z  "$a"]&&echo "yes"||echo "no"输出yesb=1  c=2   [-z  "$b"=="$c"]&&echo "yes"||echo "no" 输出no

●多重判断
判断1 -a 判断2 逻辑与
判断1 -o 判断2 逻辑或
!判断 逻辑非
eg
[-z “$a” -a 1 -ge 2 ]
7、流程控制

注意:条件判断式和中括号之间有空格
7.1单分支if语句

if [ 条件判断式 ];then   程序fi

eg
判断当前用户是否为root

#! /bin/bashtest=$(env|grep USER |cut -d "=" -f 2)if [ "$test"="root" ];then  echo "current user is root"fi

判断分区使用率

#!/bin/bashtest=$(df -h |grep sda5 |awk '{print $5}|cut -d "%" -f 1)if [ "$test" -ge "90" ];then  echo "/ is full"fi

7.2、双分支if语句

if [ 条件判断式 ];then  程序1else  程序2fi

eg
判断输入是否是一个目录

#!/bin/bashread -t 30 -p "please input derectory:" dirif [ -d "$dir" ];then  echo "input is a directory"else  echo "input isnot a directory"fi

7.3、多分支if语句

if [ 条件1 ];then  程序elif [ 条件2 ];then  程序  .....else  程序fi

7.4、多分支case语句

case $变量名 in          "值1")                程序1                ;;          "值2")               程序2               ;;          .......          *)              程序              ;; esac  

如果变量值为值1,则执行程序1,为值2,则执行程序2,为值3,则执行程序3等等,如果都不是,则执行最后一个程序
eg

#!/bin/bashread -t 30 -p "please input yes or no:" variablecase $variable in                "yes")                     echo "you input is yes"                     ;;                "no")                     echo "your input is no"                     ;;                 *)                     echo "your input is error"                     ;;esac

7.5、for循环
语法1

for 变量  in123.....    do      程序    done

eg
批量解压缩

#!/bin/bashcd /root/test/ls *.tar.gz  >  ls.logls *.tgz    >>ls.logfor i in ¥(cat ls.log)    do      tar -zxf ¥i &> /dev/null  #将执行中显示的信息丢到黑洞    donerm -rf ls.log

语法2

for ((初始值;循环控制条件; 变量变化))      do        程序      done

注意:使用的是双小括号
eg

#!/bin/bash#从1加到100s=0;for((i=1;i<=100;i=i+1))   do     s=$(($s+$i))   doneecho "the sum is:$s"    

7.6、while循环

while [ 条件判断式 ]   do   程序   done

只要条件判断式为真就一直执行
eg

#!/bin/bash#从1加到100i=1s=0while [ $i -le 100 ]   do     s=$(($s+$i))     i=$(($i+1))   doneecho "the sum is:$s"

7.7、until循环

until [ 条件判断式 ]   do   程序   done

当条件判断式为时,停止执行
eg

i=1s=0until [ $i -ge 100 ]   do     s=$(($s+$i))     i=$(($i+1))   doneecho "the sum is:$s"

8、调试脚本

检查语法错误
使用-n选项检查脚本中的语法错误,比如sh -n mem.sh

跟踪脚本执行

使用 -x选项执行脚本,比如sh -x mem.sh 1

#!/bin/bashfunction GetMem {  MEMUsage=$(ps -o vsz -p $1|grep -v VSZ)  ((MEMUsage /= 1000))  echo $MEMUsage }mem=$(GetMem $1)if [ $mem -gt 1600 ] ;then  echo “The usage of memory is larger than 1.6G” else  echo “The usage of memory is normal” fi

执行结果

++ GetMem 1+++ grep -v VSZ+++ ps -o vsz -p 1++ MEMUsage=' 19356'++ (( MEMUsage /= 1000 ))++ echo 19+ mem=19+ '[' 19 -gt 1600 ']'+ echo $'\342\200\234The' usage of memory is $'normal\342\200\235'“The usage of memory is normal”

+号代表执行的语句,多个+号反映了语句的嵌套

输出语句行号
设置环境变量export PS4=’+BASHSOURCE:{LINENO}:${FUNCNAME[0]}: ‘,然后执行 sh -x mem.sh 1
执行结果

++mem.sh:9:: GetMem 1+++mem.sh:4:GetMem: ps -o vsz -p 1+++mem.sh:4:GetMem: grep -v VSZ++mem.sh:4:GetMem: MEMUsage=' 19356'++mem.sh:5:GetMem: (( MEMUsage /= 1000 ))++mem.sh:6:GetMem: echo 19+mem.sh:9:: mem=19+mem.sh:10:: '[' 19 -gt 1600 ']'+mem.sh:13:: echo $'\342\200\234The' usage of memory is $'normal\342\200\235'“The usage of memory is normal”

调试部分脚本
使用set -x和set +x包裹需要调试的脚本,使用sh mem.sh 1 注意 :没有-x选项

#!/bin/bashfunction GetMem {  MEMUsage=$(ps -o vsz -p $1|grep -v VSZ)  ((MEMUsage /= 1000))  echo $MEMUsage }mem=$(GetMem $1)set -x             if [ $mem -gt 1600 ] ;then  echo “The usage of memory is larger than 1.6G” else  echo “The usage of memory is normal” fiset +x

执行结果

+ '[' 19 -gt 1600 ']'+ echo $'\342\200\234The' usage of memory is $'normal\342\200\235'“The usage of memory is normal”+ set +x

使用bashdb
使用bashdb软件可以进行复杂调试
9、常用脚本
查看系统信息

#!/bin/bashos=$(uname -o)echo "Operateing System Type:$os"os_name=$(cat /etc/issue |grep -e "release")echo "Opreating System  Release Version:$os_name"architecture=$(uname -m)echo "Architecture:$os_name"kernel=$(uname -r)echo "Kernel:$kernel"hostname=$(uname -n)echo "Hostname:$hostname"internal_ip=$(hostname -I)echo "InternalIp:$internal_ip"nameserver=$(cat /etc/resolv.conf |egrep "nameserver[ ]+"|awk '{print $2}')echo "NameServer:$nameserver"ping -c 2 www.baidu.com  &>/dev/null &&echo "Internet:connected"||echo "Intetnet:disconnected"who > /tmp/whoecho "Loggeg users"&& cat /tmp/whorm -rf /tmp/whosystem_mem_used=$(awk '/MemTotal/{total=$2}/MemFree/{free=$2}/^Cached/{cached=$2}/Buffers/{buffers=$2}END{print (total-free)/1024}' /proc/meminfo)echo "SystemMemoryUsed:$system_mem_used"application_mem_used=$(awk '/MemTotal/{total=$2}/MemFree/{free=$2}/^Cached/{cached=$2}/Buffers/{buffers=$2}END{print (total-free-cached-buffers)/1024}' /proc/meminfo)echo "ApplicationMemoryUsed:$application_mem_used"loadaverage=$(top -n 1|grep "load average"|awk '{print $10,$11,$12}')echo "LoadAverage:$loadaverage"diskaverage=$(df -hP |egrep -v "Filesystem|tmpfs"|awk '{print $1,$5}')echo -e "Diskaverage:\n$diskaverage"

监控CPU负载

#!/bin/bashfunction GetSysCPU {   CpuIdle=$(vmstat 1 5|sed -n '3,$p'|awk '{x=x+ $15} END{print x/5}'|awk -F. '{print $1}')   CpuNum=$((100-$CpuIdle))   echo $CpuNum }cpu=$(GetSysCPU)echo "The system CPU is $cpu"if [ $cpu -gt 90 ];then  echo "The usage of system cpu is larger than 90%" else  echo "The usage of system cpu is normal" fi

监控特定进程的cpu利用率

#!/bin/bashfunction GetCpu {    CpuValue=$(ps -p $1 -o pcpu |grep -v CPU | awk           '{print $1}' | awk -F. '{print $1}')    echo $CpuValue }function CheckCpu {    PID=$1    cpu=$(GetCpu $PID)    if [ "$cpu" -gt 80 ] ;then    {       echo “The usage of cpu is larger than 80%”    }    else    {       echo “The usage of cpu is normal”    }    fi}temp=$(ps -p $1|grep -v PID)if [ -z "$temp" ];then  echo "the process doetn't exist"else  CheckCpu $1

监控特定进程的内存使用

#!/bin/bashfunction GetMem {  MEMUsage=$(ps -o vsz -p $1|grep -v VSZ)  ((MEMUsage /= 1000))  echo $MEMUsage }mem=$(GetMem $1)if [ $mem -gt 1600 ] ;then  echo “The usage of memory is larger than 1.6G” else  echo “The usage of memory is normal” fi

监控特定分区的磁盘使用率

function GetDiskSpc {     if [ $# -ne 1 ] ;then        return 1    fi    Folder="$1$"    DiskSpace=$(df -k |grep $Folder|awk '{print $5}'|awk -F% '{print $1}')    echo $DiskSpace } DiskSpace=$(GetDiskSpc $1)echo "The system $Folder disk space is $DiskSpace%"if [ $DiskSpace -gt 90 ];then    echo "The usage of system disk($Folder) is larger than 90%"else     echo "The usage of system disk($Folder)  is normal" fi

查看某个TCP端口或UDP端口是否在监听

#!/bin/bashfunction Listening {    TCPListeningnum=$(netstat -an | grep ":$1 "|awk '$1 == "tcp" && $NF == "LISTEN" {print $0}' | wc -l)    UDPListeningnum=$(netstat -an | grep ":$1 "|awk '$1 == "udp" && $NF == "0.0.0.0:*" {print $0}' | wc -l)    (( Listeningnum=TCPListeningnum+UDPListeningnum))    if [ $Listeningnum == 0 ] ;then        echo "0"    else        echo "1"    fi}isListen=$(Listening $1)if [ $isListen -eq 1 ];then   echo "The port is listening"else   echo "The port is not listening"fi

参考
如何调试bash脚本

0 0
原创粉丝点击