shell基础(二)字符子串及类型判断符

一.变量子串

[root@mycentos shell_dir]# old="hello,world"
[root@mycentos shell_dir]# echo $old
hello,world
[root@mycentos shell_dir]# echo ${old}
hello,world
[root@mycentos shell_dir]# echo ${#old}
11
[root@mycentos shell_dir]# echo ${old//world/WORLD} 
hello,WORLD
[root@mycentos shell_dir]# echo ${old:2}           
llo,world

注:
$变量名 == ${变量名}
${#变量名} :得到变量内容的字符长度
${变量名:2} :显示从变量第三个到最后的全部字符
${变量名:2:5}显示变量第三个到第五个变量
${变量名//被替换者/替换者}  :用替换者去替换全部被替换者
${变量名/被替换者/替换者}:用替换者去替换第一个替换者
#表示从头开始匹配最短
##表示从头开始匹配最长的
%表示从尾部最短匹配最短
%%表示从尾部开始匹配最长
[root@mycentos ~]# old="abcABC123ABCabc"
[root@mycentos ~]# echo ${old#a*c}      
ABC123ABCabc
[root@mycentos ~]# echo ${old##a*c}     

[root@mycentos ~]# echo ${old%a*c} 
abcABC123ABC
[root@mycentos ~]# echo ${old%%a*c}

[root@mycentos ~]# 

实战题目一:批量修改文件名称

文件夹下有以下10个文件现在要将其中_finished去掉
stu_10299_10_finished.txt stu_10299_2_finished.txt stu_10299_4_finished.txt stu_10299_6_finished.txt stu_10299_8_finished.txt
stu_10299_1_finished.txt stu_10299_3_finished.txt stu_10299_5_finished.txt stu_10299_7_finished.txt stu_10299_9_finished.txt
第一步:处理一个文件名

[root@mycentos shell_dir]# fName=stu_10299_1_finished.txt       
[root@mycentos shell_dir]# echo ${fName//_finished/}            
stu_10299_1.txt
[root@mycentos shell_dir]# mv $fName `echo ${fName//_finished/}`

第二步:处理多个文件名

#!/bin/bash
for I in $(ls *fin*.txt)
do
        mv $I `echo ${I//_finished/}`  #将"_finished"替换成空
done
注:
更多替换方式:
http://oldboy.blog.51cto.com/2561410/711342

二.条件测试

1. test 测试表达式

2. [ 测试表达式 ]

3. [[ 测试表达式 ]]

4. ((测试表达式))

注:
一:1、2、3方式中测试表达式两侧必须有至少一个空格,4不用
二:1、2等价,3是test的扩展,4常用于计算
三:&&、||、<、>、应用于[[]]中,而不能在[]中,在[]中常用 -a 、-o 、-lt(用于整数)、-gt(用于整数)

三.文件测试

-d 文件存在且为目录则为真

-f 文件存在且为普通文件则为真

-e 文件存在则为真

-r 文件存在且可读

-w 文件存在且可写

-x 文件存在且可执行

注:
测试文件的读、写、执行等属性,不光要根据文件的rwx属性判断,还要根据当前执行测试的用户是否真的可以按照对应的权限操作该文件(root)

[ 条件1 ]&&{
    命令1
    命令2
    命令3
}
相当于
if [ 条件1 ]
    then
        命令1
        命令2
        命令3
fi
以上三个命令,若在一行则要用";"结束每一条命令

四.字符串测试

-n “字符串” :字符串长度不为0,则为真
-z “字符串” :字符串长度为0,则为真
“串1” = “串2” :串1等于串2则为真
“串1” != “串2” : 串1不等于串2才为真


1.字符串测试,一定要加上””后在比较,如[ -n “$myvar” ],避免出现错误
2.= 和 != 两端一定要有空格

五.整数比较符号

[]、test中使用的符号                   (())、[[]]中使用            
-eq                   :相等                    ==/=
-ne                   :不相等                  !=
-gt                   :大于                    >
-ge                   :大于等于                >=
-lt                   :小于                    <
-le                   :小于等于                <=

注:
1.比较符号两端需要有空格
2.若在[]中使用>、<时,需要转义,(一般不建议在[]中使用>、<)
3.尽量使用[] ,若在[]不行时,才使用[[]],尽量使用[]加 -eq的写法

六.逻辑操作符号

[]、test中使用      在[[]]、(())使用    
-a          &&          与
-o          ||          或
!           !           非

实战题目二:

输入或通过命令行传入一个字符或数字,若传入是1,就打印1,若是2就打印2,既不是1也不是2,就打印错误,并且退出程序

#!/bin/bash
echo -n "input a char:"
read var
[ "$var" == "1" ]&&{
        echo 1
        exit 0
}
[ "$var" == "2" ]&&{
        echo 2
        exit 0
}
[ "$var" != "1" -a "$var" != "2" ]&&{
        echo error
        exit 1
}
tips:
普通字符串比较多用字符串比较法,即加""进行比较,而不是整数法进行比较,整数法容易出错,除非确定是整数。

实战题目三:

开发shell脚本判断系统剩余内存的大小,如果低于100M,就邮件报警给系统管理员,并且将脚本加入系统定时任务,即每3分钟执行依次检查

#!/bin/bash
FreeMen=$(free -m|awk 'NR==3{print $NR}')
ALERT="current memory is $FreeMen"

if [ "$FreeMen" -lt 1000 ]
        then
                echo $ALERT | tee /tmp/messages.txt
                mail -s "$(date "+%F-%T")$ALERT" 862122642@qq.com < /tmp/messages.txt
fi

定时任务:

[root@mycentos script_2]# crontab -l
*/3 * * * * /bin/sh ~/scripts/script_2/1.sh &>/dev/nulll


tips:
1.tee命令:
当使用文本重定向时,文字会被重定向到文本文本中,而屏幕中没有显示,此时,若要屏幕中也显示的话就用
tee命令,而tee命令的前一个命令错误输出不会被tee读取
tee -a file1  :文件file1没有则创建,有则增加内容到后面,而不是覆盖
tee file1 file2 :同时将文本添加到file1 和file2里面
2.mail使用
    mail -s "title" 邮箱地址
3.yum -y install ntfdate
ntfdate pool.ntp.org
以上2条命令进行时间同步

七.监视Nginx服务

一:本地监视
二:远程监视
三:模拟用户测试

1.服务器本地监视
    netstat -pantu | grep 80| wc -l  :过滤关键字端口,转化为数字
    netstat -pantu | grep nginx | wc -l  :过滤关键字进程,转化为数字
    ss -pantu | grep 80 | wc -l
    lsof -i tcp:80 | wc -l
2.远端监控服务器端口
    1.nmap 127.0.0.1(自己服务器ip) -p 80 | grep open | wc -l
    2.nc -w 2 127.0.0.1  80 &>/dev/null   -w表示超时时间
3.对服务进程或进程数进行监控
    1.ps -ef | grep nginx | grep -v "grep" | wc -l
    2.ps -C nginx --no-header
4.在客户端模拟用户访问的监控方式
    wget --spider --timeout=10  --tries=2 www.baidu.com &>/dev/null  #测试链接是否正常

注:
一.wget命令解释:
1.wget命令加spider参数不会下载任何东西,spider的主要作用是测试下载链接。
当你打算进行定时下载,你应该在预定时间测试下载链接是否有效。我们可以增加–spider参数进行检查。 wget –spider URL
2.可以在以下几种情况下使用–spider参数:
定时下载之前进行检查;隔检测网站是否可用;检查网站页面的死链接;
增加重试次数。
二.read命令解释:
read命令:从标准输入获得
-p :设置提示信息
-t :设置过期时间

使用交互式接受用户输入,然后给变量赋值
注:
1.read接收的参数和脚本传参只需要一种即可
2.read接收的参数不要使用脚本传参的参数(《shell基础(二)字符子串及类型判断符》2…),read后面是普通变量
三.在用域名安装Nginx时,若出现:

No package nginx available.
Nothing to do
原因:nginx在第三方的源,而不是在centos的源中
解决方式:先yum安装epel-release,后安装nginx

实战题目四:

写出用不同的方式监视Nginx运行脚本

1.本地
#!/bin/bash

if [ $(netstat -pantu | grep nginx|wc -l) -gt 0 ] #也可换成[ $(lsof -i tcp:80 | wc -l) -gt 0 ]
        then
                echo "Nginx  is runing"
else
        echo "Nginx is stopped"
        /etc/init.d/nginx start  #启动nginx  yum安装nginx
fi
2.远程
#!/bin/bash
[ $(rpm -qa nmap| wc -l) -eq 0 ]&& yum -y install nmap &>/dev/null

if [ $(nmap 127.0.0.1 -p 80|grep "open"|wc -l) -gt 0 ]
        then
                echo "Nginx is running"
        else
                echo "Nginx is stopped"
                /etc/init.d/nginx start
fi
nc远程:
if [ $(nc -w 2 127.0.0.1 80 &>/dev/null && echo ok | grep ok| wc -l) -gt 0 ] #当nc执行成功后就输出OK
        then
                echo "Nginx is Running"
        else
                echo "Nginx is stopped"
                /etc/init.d/nginx start
fi
3.模拟客户端
1.
if [ $(curl -I http://127.0.0.1 &>/dev/null|head -1 | egrep "200|302|301"|wc -l) -eq 1 ] # -I 只取请求头
        then
                echo "Nginx is Running"
        else
                echo "Nginx is stopped"
                /etc/init.d/nginx start
fi

实战题目五:

开发rsync启动脚本

预备知识:
1.在不借助xinetd的情况下,开启和关闭rsync服务
    rsync --daemon #启动rsync
    pkill rsync  #终止rsync
2.判断服务是否启动的方法:
    1.一般检测端口和进程是否存在
    2.还可以当服务启动时,创建一个锁文件,服务停止时,删除锁文件
3.这题并不借助xinetd进行启动
4.为了简单起见此处:
  先检查rsync是否存在"rpm -qa rsync"
  然后建立一个"touch /etc/rsyncd.conf",简单起见,此处为空,实际工作时里面有内容的,此处便于rsync服务可以正常启动
#!/bin/bash
#限制参数个数
if [ $# -ne 1 ]
        then
                echo $"usage:$0 {start|stop|restart}"
                exit 1
fi
#参数类型
if [ "$1" == "start" ];then
        rsync --daemon
        sleep 2  #休息2秒,这点很重要,停止或启动后建议休息2秒后在判断
                if [ $(netstat -pantu | grep rsync | wc -l) -ne 0 ];then #如果过滤的rsync不是0,则说明启动了
                        echo "rsync is started"
                        exit 0
                fi
elif [ "$1" == "stop" ];then
        pkill rsync &>/dev/null  #停止服务的方法很多,自选即可
        sleep 2
                if [ $(netstat -pantu | grep rsync | wc -l) -eq 0 ];then
                        echo "rsync is stopped"
                        exit 0
                fi
elif [ "$1" == "restart" ];then
        killall rsync
        sleep 1
        postKill=$(netstat -pantu | grep rsync | wc -l) #关闭前和启动后都有对应的标识字符

        rsync --daemon
        sleep 1
        postStart=$(netstat -pantu | grep rsync | wc -l)

        if [ "$postKill" -eq 0 -a "$postStart" -ne 0 ];then
                echo "rsync is restarted"
                exit 0
        fi
else
        echo $"usage:$0 {start|stop|restart}" #若没有安装要求输入参数,则提示后退出脚本

fi
----------------------------------或者---------------------------------------------------------
#/bin/bash
#chkconfig:2345 21 81
#description
if [ $# -ne 1 ];then
        echo $"usage:$0 {start|stop|restart}"
        exit 1
fi

case "$1" in 
"start")
        rsync --daemon
        sleep 2

        if [ $(netstat -pantu | grep rsync | wc -l) -ge 1 ];then
                        echo "rsyncd is started"
                        exit 0
        fi
;;
"stop")
        killall rsync &>/dev/null
        sleep 2

        if [ $(netstat -pantu | grep rsync | wc -l ) -eq 0 ];then
                        echo "rsyncd is stopped"
                        exit 0
        fi
;;
"restart")
        killall rsync &>/dev/null
        sleep 1
        postKill=$(netstat -pantu | grep rsync| wc -l
)
        rsync --daemon
        sleep 1
        postStart=$(netstat -pantu | grep rsync | wc -l)

        if [ $postKill -eq 0 -a $postStart -ne 0 ];then
                echo "rsyncd is restarted"
                exit 0
        fi
;;
*)
        echo $"usage:$0 {start| stop restart}"
                exit 1
;;
esac

注:
1.修改权限:
chmod +x /etc/init.d/rsyncd
/etc/init.d/rsyncd start  :可以执行
2.加入开机自动执行服务
  方式一:
      在上述脚本中把生活解释器下2行加入:
      #chkconfig: 2345 21 81
      #description 
      注:#不能丢,后面的数字要和/etc/init.d/rc3.d/下面的文件名数字不能重复

      chkconfig --add rsyncd  #加入自启动,rsyncd 一定要放到/etc/init.d/目录下
      chkconfig --list | grep rsyncd  #检测自启动
方式二:
      在/etc/rc.local文件中加入
      /etc/init.d/rsyncd start

八.总结:

一:判断字符串是否是整数

    1.去掉0-9后看字符串是否为0
    2.expr和一个整数相加,看返回值是否为0
    3.字符子串:将不是数字的删除,看是否和原来的相等

二:计算字符长度的方法

1:[root@myredhat ~]# expr length "$string"
  15
2:[root@myredhat ~]# echo $string
  i am a good boy
  [root@myredhat ~]# echo ${string}|wc -L
  15
3:[root@myredhat ~]# echo ${string} | awk '{print length($0)}'
  15
4:[root@myredhat~]echo "${#string}"
注:
若是字符串,wc -L 则统计字符个数
若是文本,wc -L 用于打印最长行的长度,而,wc -l 显示一共的行数

三:判断字符串长度是否为0

    1.-n 、-z判断
    2.字符子串 :IP=hello,[ ${#IP} -eq 0 ]
    3.expr length "$IP" -eq 0
    4.$(echo $IP | wc -L) -eq 0
    5.$(echo $IP | awk ‘{print length}’) -eq 0
    原文作者:一名IT小学生
    原文地址: https://www.jianshu.com/p/17a5d97cba5c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞