shell脚本基础

1、执行脚本的五种方法

方法1:不需要执行权限

sh oldboy.sh

bash oldboy.sh

方法2:

cat oldboy.sh|bash

方法3:输入重定向

sh <oldboy.sh

方法4:执行权限

chmod +x /root/oldboy.sh

/root/oldboy.sh

方法5:

. /root/oldboy.sh

source /root/oldboy.sh

2、环境变量

可分为两类:

1)内置环境变量:

环境变量的名字均采用大写

2)自定义环境变量:

定义方法1:

root@ubuntu:/home/spj# export OLDBOY=1

root@ubuntu:/home/spj# echo $OLDBOY

定义方法2:

root@ubuntu:/home/spj# OLDGIRL=2

root@ubuntu:/home/spj# export OLDGIRL

root@ubuntu:/home/spj# echo $OLDGIRL

定义方法3:

root@ubuntu:/home/spj# declare -x OLD=3

root@ubuntu:/home/spj# echo $OLD

3)环境变量永久生效

优先顺序从高到低

/etc/bashrc

~/.bashrc

~/.bash_profile

/etc/prodile

配置java环境变量:# vim /etc/profile

在下方fi的位置加上以下路径:

export JAVA_HOME=/usr/local/java

export JRE_HOME=${JAVA_HOME}/jre

export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib

export PATH=.:${JAVA_HOME}/bin:$PATH

环境变量的取消:

unset 变量名

4)环境变量小结

3、普通变量(局部变量)

本地变量、自定义变量

1)定义赋值一般有以下三种写法:

2)变量的命名

3)普通变量小结

4)变量定义技巧及注意事项:

awk较特殊

4、特殊变量

1)特殊位置参数变量

2)进程特殊变量

3)变量子串知识及实践

${parameter} 返回变量$parameter的内容

${#parameter} 返回变量$parameter内容的长度(按字符),也适合特殊变量*

${parameter:offset} 在变量${parameter}中,从位置offset之后开始提取子串到结尾

${parameter:offset:length} 在变量${parameter}中,从位置offset之后开始提取长度为length的子串

#删除

${parameter#word} 从变量${parameter}【开头】开始删除最【短】匹配的word子串

${parameter##word} 从变量${parameter}【开头】开始删除最【长】匹配的word子串

${parameter%word} 从变量${parameter}结尾开始删除最短匹配的word子串

${parameter%%word} 从变量${parameter}结尾开始删除最长匹配的word子串

#类似sed替换

${parameter/pattern/string} 使用string代替第一个匹配的pattern

${parameter//pattern/string} 使用string代替所有匹配的pattern

获取变量内容长度的方法:

[root@web01 /server/scripts]# echo $OLDBOY|wc -L

22

[root@web01 /server/scripts]# echo ${#OLDBOY}

22

[root@web01 /server/scripts]# expr length "$OLDBOY"

22

[root@web01 /server/scripts]# echo $OLDBOY|awk '{print length}'

22

[root@web01 /server/scripts]# echo $OLDBOY|awk '{print length($0)}'

22

4)

5、变量的数值计算

5.1 运算符号

5.2 整数运算方法

方法1:

[root@web01 /server/scripts]# a=1

[root@web01 /server/scripts]# let a=a+1

[root@web01 /server/scripts]# echo $a

2

方法2:推荐小括号

[root@web01 /server/scripts]# a=10

[root@web01 /server/scripts]# ((a=a+1))

[root@web01 /server/scripts]# echo $a

11

方法3:尽量不用做运算

[root@web01 /server/scripts]# a=10

[root@web01 /server/scripts]# expr $a + 111

121

[root@web01 /server/scripts]# b=`expr $a + 111`

[root@web01 /server/scripts]# echo $b

121

方法4:

[root@web01 /server/scripts]# a=11

[root@web01 /server/scripts]# echo $[$a+11]

22

[root@web01 /server/scripts]# echo $[a+11]

22

[root@web01 /server/scripts]# c="$[a+11]"

[root@web01 /server/scripts]# echo $c

22

方法5:

[root@web01 /server/scripts]# a=8

[root@web01 /server/scripts]# declare -i a=a+10

[root@web01 /server/scripts]# echo $a

18

5.3 整数或者小数运算

bc

[root@web01 /server/scripts]# echo 1+2|bc

3

[root@web01 /server/scripts]# echo 1.1*2|bc

2.2

[root@web01 /server/scripts]# echo 3/2|bc

1

[root@web01 /server/scripts]# echo 3%2|bc

1

[root@web01 /server/scripts]# echo 3.33*9.99|bc

33.26

[root@web01 /server/scripts]# echo "scale=4;3.33*9.99"|bc

33.2667

[root@web01 /server/scripts]# echo 3^2|bc

9

awk

[root@web01 ~]# echo 1.1 2|awk '{print $1*$2}'

2.2

[root@web01 ~]# echo 1.1 2|awk '{print $1%$2}'

1.1

[root@web01 ~]# echo 4 2|awk '{print $1%$2}'

0

5.4 expr功能

1)计算

[root@web01 /server/scripts]# expr 10 + 10

20

2)获取字符串长度

[root@web01 /server/scripts]# a="oldgirl"

[root@web01 /server/scripts]# echo $a

oldgirl

[root@web01 /server/scripts]# expr length "$a"

7

3)判断字符串是否为整数数字或字符

[root@web01 /server/scripts]# a=1

[root@web01 /server/scripts]# expr $a + 1 &>/dev/null

[root@web01 /server/scripts]# echo $?

0

[root@web01 /server/scripts]# a=oldboy

[root@web01 /server/scripts]# expr $a + 1 &>/dev/null

[root@web01 /server/scripts]# echo $?

2

4)用来判断文件扩展名是否符合指定扩展名

[root@web01 /server/scripts]# cat judge.sh

if expr "$1" : ".*\.avi$" >/dev/null ; then

echo "好兴奋啊"

else

echo "好失望啊"

fi

[root@web01 /server/scripts]# sh judge.sh oldboy.avi

好兴奋啊

[root@web01 /server/scripts]# sh judge.sh oldboy.log

好失望啊

5.5 read命令

-p prompt:设置提示信息。

-t timeout:设置输入等待的时间,单位默认为妙。

[root@web01 ~]# read -p "请输入一个数字:" n

请输入一个数字:100

[root@web01 ~]# echo $n

100

[root@web01 ~]# read -t 10 -p "请输入两个数字:" n m

请输入两个数字:100 110

[root@web01 ~]# echo $n

100

[root@web01 ~]# echo $m

110

read读入的本质就是给变量赋值,多了交互式提示而已。

5.5.1 变量赋值的三种方式

1)定义式

a=1

2)read读入式

read -t 10 -p "请输入两个数字:" n m

n=110 m=100

3)脚本传参

$1=100

6、Shell 脚本的条件测试与比较

6.1 条件测试表达式

test -f 选项(文件存在且为普通文件则表达式成立)测试文件

test -x 选项(文件存在且为可执行文件则表达式成立)测试文件

test -z 选项(文件存在且测试字符串长度为0则表达式成立)测试文件

[root@web01 /server/scripts]# test -f a && echo ddd >a ||echo 0

0

[root@web01 /server/scripts]# cat a

cat: a: 没有那个文件或目录

[root@web01 /server/scripts]# touch a

[root@web01 /server/scripts]# test -f a && echo ddd >a ||echo 0

[root@web01 /server/scripts]# cat a

ddd

6.2 文件测试表达式

对文件的属性进行判断,然后根据结果进行处理

[ 条件1 ] && {

命令1

命令2

命令3

}

如果条件成立,那么执行三个命令。

if [ 条件1 ]

then

命令1

命令2

命令3

fi

[ 条件1 ] || {

命令1

命令2

命令3

}

如果表达式不成立,那么执行三个命令。

[ -L oldboy ] && echo 1 || echo 0

[ 条件1 ] && {

命令1

命令2

} || {

命令3

}

如果条件成立,那么执行命令1命令2,否则执行命令3。

6.3 字符串测试表达式

字符串测试表达式

[root@web01 /server/scripts]# [ -n "oldboy" ] && echo 1 || echo 0

1

[root@web01 /server/scripts]# [ -z "oldboy" ] && echo 1 || echo 0

0

[root@web01 /server/scripts]#

[root@web01 /server/scripts]# a="oldboy"

[root@web01 /server/scripts]# [ -z "$a" ] && echo 1 || echo 0

0

[root@web01 /server/scripts]# unset a

[root@web01 /server/scripts]# echo $a

[root@web01 /server/scripts]# [ -z "$a" ] && echo 1 || echo 0

1

[root@web01 /server/scripts]# [ "$a" = "oldboy" ] && echo 1 || echo 0

0

[root@web01 /server/scripts]# a="oldboy"

[root@web01 /server/scripts]# [ "$a" = "oldboy" ] && echo 1 || echo 0

1

[root@web01 /server/scripts]# [ "$a" = "oldgir" ] && echo 1 || echo 0

0

[root@web01 /server/scripts]# b="oldgirl"

[root@web01 /server/scripts]# [ "${#a}" = "${#b}" ] && echo 1 || echo 0

0

[root@web01 /server/scripts]# b="oldgir"

[root@web01 /server/scripts]# [ "${#a}" = "${#b}" ] && echo 1 || echo 0

1

[root@web01 /server/scripts]# sh 02-read.sh

作业:

[root@web01 /server/scripts]# cat 02-read.sh

read -p "请输入两个整数:" a b

echo "a-b=$(($a-$b))"

echo "a+b=$(($a+$b))"

echo "a*b=$(($a*$b))"

echo "a/b=$(($a/$b))"

echo "a**b=$(($a**$b))"

echo "a%b=$(($a%$b))"

[root@web01 /server/scripts]# cat 03-chuancan.sh

a=$1

b=$2

echo "a-b=$(($a-$b))"

echo "a+b=$(($a+$b))"

echo "a*b=$(($a*$b))"

echo "a/b=$(($a/$b))"

echo "a**b=$(($a**$b))"

echo "a%b=$(($a%$b))"

对传入的参数或者read读入的变量内容判断,如果不符合计算条件,提示用户,并退出。

read -p "请输入两个整数:" a b
expr $a + $b + 999 &>/dev/null
[ $? -ne 0 ]&&{
   echo "其中有一个输入不是数字 "
   exit 1
}
echo "a-b=4"
echo "a+b=8"
echo "a*b=12"
echo "a/b=3"
echo "a**b=36"
echo "a%b=0"
#!/bin/bash
#1.判断是不是两个数
[ $# -ne 2 ] && {
		echo "Usage:$0 num1 num2"
    exit 1
}
#2.判断是否为数字
expr $1 + $2 + 999 &>/dev/null
[ $? -ne 0 ] &&{
		echo "请输入两个整数"
    exit 2
}
#3.开始计算
echo "a-b=4"
echo "a+b=8"
echo "a*b=12"
echo "a/b=3"
echo "a**b=36"
echo "a%b=0"

6.4 整数二元比较操作符

6.5 逻辑操作符

read -p "请输入一个数字" a
[ $a  -eq 1 ] && {
    echo "1"
    exit 0
}

[ $a  -eq 2 ] && {
    echo "2"
    exit 0
}

[ $a -ne 1 -a $a -ne 2 ]&&{
    echo "error"
    exit 0
}

7、if 结构条件句

7.1 单分支结构

if 语句的嵌套

7.2 双分支结构

#!/bin/bush
free_mem=`free -m|awk 'NR==2{print $NF}'`
if [ $free_men -lt 100 ]
then
		echo "内存不足,当前是$free_mem" |tee /tmp/mem.log
    mail -s "$(date) 内存报警" pj_song@163.com </tmp/men.log
else
		echo "内存充足"
fi

7.3 多分支结构

作业:

1、判断nginx/mysql是否活着,如果没有活着就邮件报警,每三分钟执行一次。

2、进程是否存在,端口是否开启,curl/wget访问URL

3、写一个rsync/sersync/nginx的启动脚本。

/etc/init.d/rsync {start|stop|restart}

C6:用chkconfig实现开机自启动管理。

C7:用systemctl实现开机自启动管理。

1、服务器本地端口监控:

过滤端口然后转成行数。

netstat -lntup|grep nginx|wc -l(推荐)

ss -lntup|grep nginx|wc -l

lsof -i :80|wc -l

2、远端端口监控:

看返回的行数,为1正常,否则不正常。

nmap 127.0.0.1 -p 80|grep open|wc -l(推荐)

echo -e "\n"|telnet 127.0.0.1 80 2>/dev/null|grep Connected|wc -l

看返回值,为0正常。

[root@web01 ~]# nc -z 127.0.0.1 80

[root@web01 ~]# echo $?

0

nc的控制参数不少,常用的几个参数如下所列:

1) -l

用于指定nc将处于侦听模式。指定该参数,则意味着nc被当作server,侦听并接受连接,而非向其它地址发起连接。

2) -p <port>

暂未用到(老版本的nc可能需要在端口号前加-p参数,下面测试环境是centos6.6,nc版本是nc-1.84,未用到-p参数)

3) -s

指定发送数据的源IP地址,适用于多网卡机

4) -u

指定nc使用UDP协议,默认为TCP

5) -v

输出交互或出错信息,新手调试时尤为有用

6)-w

超时秒数,后面跟数字

7)-z

表示zero,表示扫描时不发送任何数据

3、客户端模拟监控:看返回值或者看返回字符串

wget -q 127.0.0.1 &>/dev/null (推荐)

echo $?

curl 127.0.0.1 &>/dev/null

echo $?

7

看返回字符串是否为www7

[root@web01 /etc/nginx/conf.d]# curl -s 127.0.0.1 2>/dev/null(推荐)

www7

环境准备:

[root@oldboy ~]# touch /etc/rsyncd.conf

[root@oldboy ~]# rsync --daemon

[root@oldboy ~]# lsof -i :873

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

rsync 1690 root 4u IPv4 14658 0t0 TCP *:rsync (LISTEN)

rsync 1690 root 5u IPv6 14659 0t0 TCP *:rsync (LISTEN)

[root@oldboy ~]# pkill rsync

[root@oldboy ~]# lsof -i :873

启动脚本:

3、写一个rsync/sersync/nginx的启动脚本。

/etc/init.d/rsync {start|stop|restart}

C6:用chkconfig实现开机自启动管理。

C7:用systemctl实现开机自启动管理。

1)启动:rsync --daemon

2)停止:pkill rsync

kill `cat /var/run/rsyncd.pid`

3)监控手段:netstat -lntup|grep rsync|wc -l

/etc/init.d/rsyncd {start|stop|restart}

[root@oldboy init.d]# cat rsyncd

#!/bin/bash

if [ "$1" = "start" ]

then

if [ -f /var/run/rsyncd.pid -a -s /var/run/rsyncd.pid ]

then

:

else

rsync --daemon

fi

elif [ "$1" = "stop" ]

then

if [ -f /var/run/rsyncd.pid -a -s /var/run/rsyncd.pid ]

then

kill `cat /var/run/rsyncd.pid`

else

echo "Failed to stop rsync Unit rsync not loaded."

exit 1

fi

elif [ "$1" = "restart" ]

then

if [ -f /var/run/rsyncd.pid -a -s /var/run/rsyncd.pid ]

then

kill `cat /var/run/rsyncd.pid`

fi

sleep 2

if [ -f /var/run/rsyncd.pid -a -s /var/run/rsyncd.pid ]

then

:

else

rsync --daemon

fi

else

echo "Usage;$0 {start|stop|restart}"

fi

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值