SHELL学习笔记3

来源:互联网 发布:大数据都要学什么 编辑:程序博客网 时间:2024/04/29 22:36

1.if条件句

单分支结构 
语法:
if [条件]
  then
          指令
fi
或者:
if [条件]; then                  #分号相当于命令换行。
                       指令
fi
特殊写法:if [ -f "$file1" ]; then echo 1 ; fi 相当于 [ -f "$file1" ] && echo 1
简单判断两个数字的大小
#!/bin/bash
read -p "Pls input two number:" a b
if [ $a -gt $b ]
then
        echo "$a > $b"
else
        echo "$a < $b"
fi
另外还有一个例子:
#!/bin/bash
a="/uestc/file1"
if [ -f "$a" ]
then
     echo "It exits"
     cat "$a"
else
     echo "There is no such file"
     touch $a
fi
另一个例子:
#!/bin/bash
$FILEPATH="/tmp/uestc"
[ ! -d "$FILEPATH" ] && mkdir -p $FILEPATH
cd $PATH
if [ -f "$FILEPATH/file.sh" ]
then
   echo "file.sh is exist"
   cat "$FILEPATH/file.sh"
   exit 0
else
   touch "$FILEPATH/file.sh"
   echo "$FILEPATH/file.sh has been created"
fi
思考题目:
判断系统内存大小,低于100MB就进行邮件报警
linux系统中查看系统内存的命令为:free -m 而Linux系统有个特性,只要是不用的内存会被缓存(caching),所以说真正可用的内存为buffers/cache中的free项。
我们这里解释复习一下awk的用法
awk指定分隔符号的选项为-F ":" ;
awk -F: '/root/ {print $7}' #这行命令为指定分隔符为:,截取含有root关键字的某一行,然后打印出这一行的第七个字符。
我们先截取出剩余内存数量:free -m | awk '/buffers\// {print $4}'
#!/bin/bash
cur_free=`free -m | awk '/buffers\// {print $4}'`
if[[ $cru_free -lt 4000 ]]
then
       echo "Low Memory!! CURRENT MEMMORY=$cur_free"
       echo "Low MEM" | mail -s "Low MEM current free mem is $cur_free" 639188185@qq.com
fi
如我我们想每分钟检查一次该如何做呢?
crontab -e
* * * * * /bin/sh /uestc/mem1.sh > /dev/null      #一分钟检查一次
*  *  *  *  *  command 
分 时 日 月 周 命令 
第1列表示分钟1~59 每分钟用*或者 */1表示 
第2列表示小时1~23(0表示0点) 
第3列表示日期1~31 
第4列表示月份1~12 
第5列标识号星期0~6(0表示星期天) 
第6列要运行的命令 放大法

2.双分支和多分支if语句

if 条件
  then
         指令集
else
         指令集
fi
特殊用法:if [ -f"$file1" ]; then echo 1; else echo 0相当于:[ -f "$file1" ] && echo 1 || echo 0

多分支:
if 条件
   then
           指令
elif 条件
     then
             指令
else
多分支比较:
#!/bin/bash
read -p "Plase input a integer: " a
if [ $a -gt 6 ]
then
    echo "$a is larger than 6"
elif [ $a -lt 6 ]
    then
        echo "$a is litter than 6"
else
    echo "$a equals 6"
fi
严格的数字判断
首先判断输入的是否全为数字:之前的判断是用expr进行的:expr $a + 0&>/dev/null ; [$? ! -eq 0] && echo "Please input integer"
这里呢我们换一种思路:把输入的数字去掉,然后看是否为空:[ -z "`echo $a | sed 's/[0-9]//g'`" ]  && echo "all num" || echo "notall"
另外还有一思路:把非数字部分删除看是否等于其本身:[ -n "$num" -a "$num" = "${num/[^0-9]}//" ] && echo "It is num"
#!/bin/bash
A="123k"
[ -n "$A" -a "$A" = "${A/[^0-9]/ /}" ] && echo "Integer" || echo "No"

3.监控MySQL服务的实战例子

思路:首先是过滤出MySQL端口进行判断:netstat -lnt | awk -F '[ :]+' '{print $5}'
这个主意awk的用法:不同分割符,并且同一分隔符的数量也不相同
我们可以使用以下方法:
#!/bin/bash
PortNum=`netstat -lnt | grep 3306 | wc -l`               #mysql默认的端口号为3306
if [ $PortNum -ne 1 ]; then
    /data/3306/mysql start
fi
优化:
当mysql启动之后我们首先去查看有多少个进程(注意一定要把自己查看进程的进程给排除掉):ps -aux | grep mysqld | grep -v grep  2 | wc -l
即当mysql正常启动时端口号为1个进程为2个。
#!/bin/bash
PortNum=`netstat -lnt | grep 3306 | wc -l`
Process=`ps aux | grep mysqld | grep -v grep | wc -l`
LogPath="/tmp/mysql.log"
if [ $PortNum -eq 1 -a $Process -eq 2 ]; then
   echo "MySql is running Now!"
else
   service mysqld start>$LogPath
   sleep 10
   PortNum=`netstat -lnt | grep 3306 | wc -l`
   MysqlProcessNum=`ps aux | grep mysqld | grep -v grep | wc -l`
   if [ $PortNum -ne 1 -a $MysqlProcessNum -ne 2 ]; then
   while true                        #while死循环确保mysqld进程被彻底杀死
   do
   killall -9 mysqld &>/dev/null
   [ $? -ne 0 ] && break             #$?不等于0说明没有进程可杀,代表进程已经被杀死了
   sleep 1
   done
   service mysqld start>>$LogPath && status="Successful" || status="Failure"
   mail -s "MySql startup status is $status" 639188185@qq.com <$LogPath
   service mysqld start
   fi
fi

4.MySQL的实例2

模拟web服务器,通过MySQL账户连接MySQL,然后根据返回命令状态或返回内容确认MySQL是否正常
待补充

5.如何查看远端web服务是否开通tcp 80端口

1>echo -e "\n" | telnet baidu.com 80 | grep Connected
2>通过nmap来检查端口是否通畅:nmap baidu.com -p 80
3>通过nc命令检查端口是否通畅:nc -w 5 www.baidu.com 80 && echo OK || NOT      #-w timeout指定超时时间

7.case结构条件句

case "字符串变量" in
       值1 指令
;;
       值2 指令
;;
       *) 指令
esac
第一个简单的例子:
#!/bin/bash
read -p "Pls input a integer: " ans
case "$ans" in
1)
   echo "you have input 1"
;;
2)
   echo "you have input 2"
;;
[3-9])
   echo "you have input $ans"
;;
*)
   echo "Pls input less than 9"
   exit;
i;;
esac

给字体加颜色:
echo -e "\033[30m 黑字体 UESTC \033[0m"
echo -e "\033[31m 红字体 UESTC \033[0m"
echo -e "\033[32m 绿字体 UESTC \033[0m"
echo -e "\033[33m 黄字体 UESTC \033[0m"
echo -e "\033[34m 蓝字体 UESTC \033[0m"
echo -e "\033[35m 紫字体 UESTC \033[0m"
echo -e "\033[36m 天蓝字体 UESTC \033[0m"
echo -e "\033[37m 白字体 UESTC \033[0m"

8.启动apache的脚本

有关apache的启动脚本,我们最好研究一下/etc/init.d/httpd这个文件
#!/bin/bash
#
# httpd        Startup script for the Apache HTTP Server
#
# chkconfig: - 85 15
# description: The Apache HTTP Server is an efficient and extensible  \
#       server implementing the current HTTP standards.
# processname: httpd
# config: /etc/httpd/conf/httpd.conf
# config: /etc/sysconfig/httpd
# pidfile: /var/run/httpd/httpd.pid
#
### BEGIN INIT INFO
# Provides: httpd
# Required-Start: $local_fs $remote_fs $network $named
# Required-Stop: $local_fs $remote_fs $network
# Should-Start: distcache
# Short-Description: start and stop Apache HTTP Server
# Description: The Apache HTTP Server is an extensible server 
#  implementing the current HTTP standards.
### END INIT INFO


# Source function library.
. /etc/rc.d/init.d/functions


if [ -f /etc/sysconfig/httpd ]; then
        . /etc/sysconfig/httpd
fi


# Start httpd in the C locale by default.
HTTPD_LANG=${HTTPD_LANG-"C"}


# This will prevent initlog from swallowing up a pass-phrase prompt if
# mod_ssl needs a pass-phrase from the user.
INITLOG_ARGS=""


# Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server
# with the thread-based "worker" MPM; BE WARNED that some modules may not
# work correctly with a thread-based MPM; notably PHP will refuse to start.


# Path to the apachectl script, server binary, and short-form for messages.
apachectl=/usr/sbin/apachectl
httpd=${HTTPD-/usr/sbin/httpd}
prog=httpd
pidfile=${PIDFILE-/var/run/httpd/httpd.pid}
lockfile=${LOCKFILE-/var/lock/subsys/httpd}
RETVAL=0
STOP_TIMEOUT=${STOP_TIMEOUT-10}


# The semantics of these two functions differ from the way apachectl does
# things -- attempting to start while running is a failure, and shutdown
# when not running is also a failure.  So we just do it the way init scripts
# are expected to behave here.
start() {
        echo -n $"Starting $prog: "
        LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch ${lockfile}
        return $RETVAL
}


# When stopping httpd, a delay (of default 10 second) is required
# before SIGKILLing the httpd parent; this gives enough time for the
# httpd parent to SIGKILL any errant children.
stop() {
echo -n $"Stopping $prog: "
killproc -p ${pidfile} -d ${STOP_TIMEOUT} $httpd
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}
reload() {
    echo -n $"Reloading $prog: "
    if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/null; then
        RETVAL=6
        echo $"not reloading due to configuration syntax error"
        failure $"not reloading $httpd due to configuration syntax error"
    else
        # Force LSB behaviour from killproc
        LSB=1 killproc -p ${pidfile} $httpd -HUP
        RETVAL=$?
        if [ $RETVAL -eq 7 ]; then
            failure $"httpd shutdown"
        fi
    fi
    echo
}


# See how we were called.
case "$1" in
  start)
start
;;
  stop)
stop
;;
  status)
        status -p ${pidfile} $httpd
RETVAL=$?
;;
  restart)
stop
start
;;
  condrestart|try-restart)
if status -p ${pidfile} $httpd >&/dev/null; then
stop
start
fi
;;
  force-reload|reload)
        reload
;;
  graceful|help|configtest|fullstatus)
$apachectl $@
RETVAL=$?
;;
  *)
echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest}"
RETVAL=2
esac


exit $RETVAL

9.while循环和until循环

while语法:满足条件执行
while 条件
         do
         指令
done

until语法:满足条件退出
until 条件
          do
          指令
简单实例:
#!/bin/bash
while true                #while true表示条件永远为真,因此会一种运行,像死循环一样,我们称之为守护进程。
do
   uptime
   sleep 2
done

我们知道计划任务最短间隔为1min(crontab)如果想让其5s执行一次就用到守护进程了。
功能和用途如下表:


10.for循环结构
语法1:
for 变量名 in 变量取值列表
do
     指令
done
提示:在此结构中“in 变量取值列表”可以省略,省略时相当于in “$@”,使用for i就相当于for i in "$@"

语法2:
for((exp1;exp2;exp3))
do
     指令
done
实例:
打印5-1
#!/bin/bash
for num in 5 4 3 2 1
do
   echo $num
done
或者:echo {5..1} 或者seq -s " " 5 -1 1
题目:获取当前目录下的目录作为变量列表打印输出:
#!/bin/bash
for num in `ls -F | grep /`
do 
    echo $num
done
题目:用for循环批量修改格式:把所有的jpg改为gif
我们先创建10个jpg文件:touch {10..1}.jpg
#!/bin/bash
for name in `ls *.jpe`
do
    mv $name `echo $name | cut -d. -f1`.gif
done
 我们还可以用rename
rename .jpg .gif *.jpg
还以用awk命令:ls *\.jpd | awk -F '.' '{print $1}'
基本语法到这就讲完了,剩余的去大量的做案例!!!
最后总结一下awk的用法:
awk -F ':' '{print $1"\t"$7}' /etc/passwd     #-F是域分割符。
awk -F: '/root/' /etc/passwd            #我们要找有root关键字的所有行
awk -F: '/root/{print $3}' /etc/passwd          #我们找到有root关键字的行并对改行进行处理

我们再讲两个awk常用的内置变量:NR、NF
awk -F: 'NR==10{print $3}' /etc/passwd               #这个意思是打印passwd文件的第10行中的第3部分
而NF代表浏览记录的域的个数,$NF则表示最后一个域。
例如:
[root@localhost ~]# awk -F: 'NR==10{print $3"\n"NF"\n"$NF}' /etc/passwd
10
7
/sbin/nologin
0 0