shell笔记

时间:2016-05-14 08:58:44   收藏:0   阅读:1796

~20~shell

shell是一个命令解释器

查看系统的shell

[root@liwx ~]# cat /etc/shells

/bin/sh

/bin/bash

/sbin/nologin

/bin/dash

/bin/tcsh

/bin/csh

 

[root@liwx ~]# echo $SHELL

/bin/bash

 

 

 

python运维开发实战课程,课程表是:http://oldboy.blog.51cto.com/2561410/1123127

 

shell         处理操作系统底层的脚本,简单,易用,高效

python     处理复杂的逻辑程序,

php            前端的页面开发,web的开发

java        后台的开发,更复杂的逻辑程序,安全性更好些

 

 

 

脚本的第一行

#!/bin/bash

#!/bin/sh

 

技术分享

 

 

 

[root@liwx scripts]# ls -l `which sh`

lrwxrwxrwx. 1 root root 4 May 15 10:33 /bin/sh -> bash

 

[root@MySQL ~]# tail -2 /etc/init.d/functions 
echo "I am oldboy linux"
}
[root@MySQL ~]# cat test.sh 
. /etc/init.d/functions
oldboy

 

脚本开发的基本规范及习惯

1)脚本第一行指定脚本解释器

2)脚本开头加版本版权等信息

3)脚本中尽量不用中文注释

4)脚本以.sh为扩展名

5)成对的符号要一次性写全,然后退格,流程语句要一次性写完,代码要缩进

 

老师推荐的shell书

http://www.gnu.org/software/bash/manual/bash.html
man bash
Unix shell范例精解(第4版)-老男孩推荐大家此书
shell-abs-3.9.1_cn_老男孩培训推荐
http://manual.51yip.com/shell/

 

 

 

shell变量

变量类型:

    1.环境变量

    2.局部变量

环境变量(一般大写)

env|grep -i root

printenv

export

USER=root

MAIL=/var/spool/mail/root

PATH=/application/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

HOME=/root

LOGNAME=root

OLDPWD=/root

 

[root@liwx scripts]# echo $UID

0

[root@liwx scripts]# echo $USER

root

[root@liwx scripts]# echo $HOME

/root

[root@liwx scripts]# echo $BASH

/bin/bash

[root@liwx scripts]# echo $PS1

[\u@\h \W]\$

 

全局环境变量地点

/etc/profile.d

/etc/profile

/etc/bashrc

 

用户环境变量

[root@liwx scripts]# ls -la /home/liwx/

-rw-r--r--. 1 liwx liwx 176 Oct 16 2014 .bash_profile

-rw-r--r--. 1 liwx liwx 124 Oct 16 2014 .bashrc

 

设置环境变量

export LANG=en

或者

LANG=en

export LANG

 

环境变量的显示与取消

显示 $HOME(大写)

        env

        set

 

unset取消环境变量

unset OLDBOY

[root@mysql-2 ~]# echo $LIEX

 

[root@mysql-2 ~]# echo $LIWX

22

[root@mysql-2 ~]# unset LIWX

[root@mysql-2 ~]# echo $LIWX

 

 

局部变量

    变量名=value

    变量名=‘value‘

    变量名="value"

一般是有字母,数字,下划线组成,以字母开头

    oldboy,oldboy123,oldboy_training

 

source或者.会把脚本里的变量定义到系统

[root@mysql-2 bianliang]# sh test1.sh

123

[root@mysql-2 bianliang]# echo $liwx

 

[root@mysql-2 bianliang]# source test1.sh

123

[root@mysql-2 bianliang]# echo $liwx

123

 

 

单引号,双引号

无引号 简单的,连续的,整体的,路径,字符串,有命令要用反引号,可用双引号替代

‘‘    所见即所得 不解析变量

""    解析变量,

``        一般用于引用命令,执行的时候命令会被执行,相当于$()

技术分享

 

1,在脚本中第一普通字符串变量,尽量用双引号

2,单纯数字内容可以不加引号.

3,希望原样输出加单引号,

4,awk,sed单引号和双引号里面的变量,正好与shell相反.

 

一道实用linux运维问题的9种shell解答方法

http://oldboy.blog.51cto.com/2561410/760192

 

 

把命令作为变量

a=`ls`

    a=$(ls)

tar zcvf etc_$(date +%F).tar.gz   /etc/hosts
ls -lrt
rm -f etc_2015-08-11.tar.gz 
tar zcvf etc_`date +%F`.tar.gz   /etc/hosts

 

 

变量定义小结

    普通变量:

    a=1             连续的数字

    a="/etc/rc.local $USER"

    a=‘$USER‘    原样输出

    命令变量

    a=`ls`        反引号

    a=$()

 

变量定义小技巧

    ``        tab键上边的,不是单引号

     $        变量前加$,可以echo,print取变量的值,

{}        边界问题

""    养成所用字符串变量用""括起来

 

技术分享

 

特殊变量

1)$1...$n    传参变量

    用法:启动脚本

    $n 获取当前执行的shell脚本的第n个参数值,n=1..9 ,当 n 为0时表示脚本的文件名,如果n大于9,用大括号括起来${10},参数以空格隔开。

 

2)$0    取脚本的名字,也包含路径

    用法:报错时,取脚本的路径和名字

[root@liwx home]# cat /server/scripts/test.sh

dirname $0        #取路径

basename $0    #取脚本名

[root@liwx home]# sh /server/scripts/test.sh

/server/scripts

test.sh

技术分享

 

3)$# 取传参的个数

    用法:用来判断参数的个数

    [ $# -ne 2 ] 如不等于2

 

进程状态变量

4)$? 获取上一次命令执行情况的返回值

    0        成功运行

    2        权限拒绝

    1-255    失败

在脚本里调用,一般用exit0,脚本返回值给$?

函数里return0返回 返回值给$?

    用法

1)判断命令或者脚本是否执行成功

2)通过在脚本里执行exit数字,则脚本返回这个数字给$?

如果是函数用return 数字,返回数字给$?

[root@MySQL 01]# cat t1.sh 
#!/bin/sh
[ $# -ne 2 ] && {
  echo "$0 ARG1 ARG2"
  exit 111     #赋值给当前shell的$?
}
[root@mysql-2 bianliang]# sh test1.sh

test1.sh ARG1 ARG2

[root@mysql-2 bianliang]# echo $?

111

 

$*和$@

$* 将所有的参数视为单个字符串"$1$2$3"

$@ 接受所有参数                 "$1""$2""$3"    

$* 和  $@的区别?
$*是获取所有传参的参数,他会把将所有的参数视为单个字符串
$@它把程序里的所有参数,以"$1""$2""$3"来显示,每一个都是独立的个体
$*所有传参的参数当成一个
$@所有参数当成单个的个体

 

其他:linux下set和eval的使用小案例精彩解答(特殊位置变量用法)
http://oldboy.blog.51cto.com/2561410/1175971

 

$$ 当前shell执行的进程号,pid

kill -USR2 `cat /tmp/a.pid`

 

#!/bin/sh
pidpath=/tmp/a.pid
if [ -f "$pidpath" ] 
  then 
      kill -USR2 `cat $pidpath` >/dev/null 2>&1
      rm -f $pidpath
fi
echo $$ >$pidpath
sleep 300

 

$! 执行上一次命令的PID

 

man bash

变量字串的常用操作

1.统计字符串长度的方法

OLDBOY="I am oldboy"

法1

echo ${#OLDBOY}

11

法2

echo $OLDBOY|wc -L

11

法3

expr length "$OLDBOY"
11

 

面试题,取字符串小于6的单词

for n in I am oldboy linux welcome to our training.
do
   if [ ${#n} -lt 6 ]
    then
      echo $n
   fi
done

 

2.截取一部分内容输出

[root@MySQL 01]# echo $OLDBOY
I am oldboy
[root@MySQL 01]# echo ${OLDBOY:2}
am oldboy
[root@MySQL 01]# echo ${OLDBOY:2:6}
am old
[root@MySQL 01]# echo ${OLDBOY:2:2}
am
[root@MySQL 01]# echo ${OLDBOY:3:2}
m
[root@MySQL 01]# echo ${OLDBOY:3:3}
m o
[root@MySQL 01]# echo ${OLDBOY:3}  
m oldboy

 

[root@MySQL 01]# echo $OLDBOY
I am oldboy
[root@MySQL 01]# echo ${OLDBOY:2}
am oldboy
[root@MySQL 01]# echo ${OLDBOY:2:6}
am old
[root@MySQL 01]# echo ${OLDBOY:2:2}
am
[root@MySQL 01]# echo ${OLDBOY:3:2}
m
[root@MySQL 01]# echo ${OLDBOY:3:3}
m o
[root@MySQL 01]# echo ${OLDBOY:3}  
m oldboy

 

${OLD#abc}        从开头开始删除匹配的最短长度字符串

${OLD##abc}    从开头开始删除匹配的最长长度字符串
[root@MySQL 01]# OLDBOY=abcABC123ABCabc
[root@MySQL 01]# echo ${OLDBOY}        
abcABC123ABCabc
[root@MySQL 01]# echo ${OLDBOY#a*C}
123ABCabc
[root@MySQL 01]# echo ${OLDBOY#a*c}
ABC123ABCabc
[root@MySQL 01]# echo ${OLDBOY##a*c}

[root@MySQL 01]# echo ${OLDBOY##a*C}
abc

 

 

3.变量删除

${%}    从结尾开始删除匹配的最短长度字符串

${##}    从结尾开始删除匹配的最长长度字符串
[root@MySQL 01]# echo ${OLDBOY%a*C} 
abcABC123ABCabc
[root@MySQL 01]# echo ${OLDBOY%a*c}
abcABC123ABC
[root@MySQL 01]# echo ${OLDBOY%C*c}
abcABC123AB
[root@MySQL 01]# echo ${OLDBOY%%C*c}
abcAB
[root@MySQL 01]# echo ${OLDBOY%%C*c}

 

 

技术分享

 

[root@MySQL 01]# OLDBOY="I am oldboy oldboy oldgirl"

[root@MySQL 01]# echo ${OLDBOY/oldboy/etiantian}    
I am etiantian oldboy oldgirl
[root@MySQL 01]# echo ${OLDBOY/#I*oldboy/etiantian}
etiantian oldgirl
[root@MySQL 01]# echo ${OLDBOY/%rl/etiantian}      
I am oldboy oldboy oldgietiantian

 

小结:

    #    开头删除匹配最短

    ##    开头删除匹配最长

    %    结尾删除匹配最短

    $$    结尾删除配置最长

 

 

-防止空值

-防止空值,备胎

[root@MySQL 01]# pidfile=${PIDFILE-/var/run/httpd/httpd.pid}
[root@MySQL 01]# echo $pidfile
/var/run/httpd/httpd.pid

[root@MySQL 01]# PIDFILE=/etc/rc.local 
[root@MySQL 01]# pidfile=${PIDFILE-/var/run/httpd/httpd.pid}
[root@MySQL 01]# echo $pidfile        
/etc/rc.local

 

 

变量的数值计算

变量计算的常用命令

 

(())、let、expr、bc(可以计算小数)  $[],其它都是整数。

 

1.(())

1.(())用法(常用)

* / %                                           乘,处,取余    

**                                                 幂运算

+=,-=                                            a+=1 相当于 a=a+1

技术分享

 

shell的运算实例

[root@liwx home]# ((a=1+2**3-4%3))

[root@liwx home]# echo $a

8

[root@mysql-2 bianliang]# b=$((1+2**3-4%3))

[root@mysql-2 bianliang]# echo $b

8

[root@liwx home]# echo $((1+2**3-4%3))

8

 

记忆方法:++,--
变量a在前,表达式的值为a,然后a自增或自减,变量a在符号后,表达式值自增或自减,然后a值自增或自减。

 

i++[root@MySQL 01]# myvar=99
[root@MySQL 01]# echo $((myvar+1)) 
100
[root@MySQL 01]# echo $((myvar-1))
98
[root@MySQL 01]# echo $((myvar-1))
98

 

[root@MySQL 01]# echo $((100/5))    
20
[root@MySQL 01]# echo $((100+5))
105
[root@MySQL 01]# echo $((100*5))
500
[root@MySQL 01]# echo $((100**5))
10000000000
[root@MySQL 01]# echo $((100%5)) 
0

 

 

[root@liwx scripts]# vim test.sh

 

 

 

#!/bin/bash

a=6

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 ))"

 

[root@liwx scripts]# sh test.sh

a-b =4

a+b =8

a*b =12

a/b =3

a**b =36

a%b =0

 

 

[root@liwx scripts]# vim test.sh

 

#!/bin/bash

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 ))"

 

[root@liwx scripts]# sh test.sh 10 5

a-b =5

a+b =15

a*b =50

a/b =2

a**b =100000

a%b =0

 

网友的例子:
http://chenhao6.blog.51cto.com/6228054/1232070
http://zhangbo.blog.51cto.com/350645/1172900
http://blog.163.com/shaohj_1999@126/blog/static/634068512011388519129/
作业:本周每人完成一个简单的四则运算计算器功能

 

 

2.let

[root@MySQL 01]# i=1      
[root@MySQL 01]# let i=i+100
[root@MySQL 01]# echo $i
101

提示:let i=i+8等同于((i=i+8)),但后者效率更高

 

 

3.expr计算

[root@liwx scripts]# expr 2 + 2

4

[root@liwx scripts]# expr 2 * 2

expr: syntax error

[root@liwx scripts]# expr 2 \* 2

4

[root@liwx scripts]# expr 2 - 2

0

[root@liwx scripts]# expr 2 % 2

0

 

[root@mysql-2 bianliang]# expr $[2*3]

6

[root@mysql-2 bianliang]# expr $[2+3]

5

[root@mysql-2 bianliang]# expr $[2-3]

-1

 

 

expr 运算好两边必须有 "空格"

4.判断扩展名

if expr "$1" : ".*\.pub" &>/dev/null
  then 
   echo "you are using $1"
else
   echo "pls use *.pub file"
fi

 

5.判断变量是否为整数

[root@MySQL 01]# cat judge_int.sh 
read -p "Pls input:" a
expr $a + 1 &>/dev/null
[ $? -eq 0 ] && echo int||echo chars

 

法2

expr match整数判断
[[ `expr match "$a" "[0-9][0-9]*$"` == 0 ]] && {
        echo "the first is not a num"
        exit 3
}

 

6.计算字符串长度

 

[root@MySQL 01]# chars=`seq -s" " 100`
[root@MySQL 01]# echo $chars
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
法1(最常用,效率最高)

[root@MySQL 01]# echo ${#chars}
291

法2
[root@MySQL 01]# echo $(expr length "$chars")
291

法3
[root@MySQL 01]# echo ${chars}|wc -L
291

 


[root@MySQL 01]# time for i in $(seq 11111);do count=${#chars};done;

real    0m0.512s
user    0m0.503s
sys     0m0.001s

[root@MySQL 01]# time for i in $(seq 11111);do count=`echo ${chars}|wc -L`;done;

real    0m21.410s
user    0m0.869s
sys     0m2.123s
[root@MySQL 01]# time for i in $(seq 11111);do count=`echo expr length "${chars}"`;done;

real    0m5.702s
user    0m0.391s
sys     0m1.230s
[root@MySQL 01]# grep "host" /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 MySQL
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

 

7.bc计算器

bc计算器

[root@liwx scripts]# bc

bc 1.06.95

Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.

This is free software with ABSOLUTELY NO WARRANTY.

For details type `warranty‘.

5.6-5.5

.1

 

bc是unix下的计算器,可以算小数

[root@liwx scripts]# i=2

[root@liwx scripts]# i=`echo $i+1|bc`

[root@liwx scripts]# echo $i

3

 

[root@liwx scripts]# echo "5.6-5.4"|bc

.2

 

#保留几位

[root@MySQL 01]# echo "scale=3;5.23 / 3.13"|bc
1.670

 

 

7.awk方法

echo "$NEWCONN1 $NEWCONN2" |awk ‘{print ($2-$1)/5}‘

awk也可以计算小数……

[root@liwx scripts]# echo "5.6 5.5"|awk ‘{print ($1-$2)}‘

0.1

[root@liwx scripts]# echo "5.6 5.5"|awk ‘{print ($1-$2)/5}‘

0.02

 

范例:通过一条命令计算输出1+2+3..+10的表达式,并计算出结果,使用bc计算?

输出内容如:1+2+3+4+5+6+7+8+9+10=55

法1

echo "`seq -s ‘+‘ 10`="$((`seq -s "+" 10`))
1+2+3+4+5+6+7+8+9+10=55

法2
echo `seq -s ‘+‘ 10`=`seq -s "+" 10|bc`
1+2+3+4+5+6+7+8+9+10=55

法3
echo `seq -s ‘+‘ 10`=`seq -s " + " 10|xargs expr`
1+2+3+4+5+6+7+8+9+10=55

法4
echo {1..9}"+" 10 =`echo {1..9}"+" 10|bc`|sed ‘s# ##g‘
1+2+3+4+5+6+7+8+9+10=55

 

 

8.$[]

[root@MySQL 01]# i=1
[root@MySQL 01]# i=$[ i + 1 ]
[root@MySQL 01]# echo $i
2

 

read变量赋值

语法

read 参数 变量名

    -p 设置提示信息

    -t    设置输入等待的时间

 

[root@mysql-2 scripts]# read -t 5 -p "pls input:"a #a前面要有空格

pls input:1

[root@mysql-2 scripts]# echo $a

1

[root@mysql-2 scripts]# read -t 5 -p "pls input:" a b c

pls input:1 2 3

[root@mysql-2 scripts]# echo $a $b $c

1 2 3

 

 

 

 

 

 

用shell脚本实现杨辉三角的3个实例(第一种为重点h)
http://oldboy.blog.51cto.com/2561410/756234

 

 

19:38 2015/8/11
课后作业:
1、shell脚本基础,shell介绍,重要性
2、写脚本规范,脚本的建立和执行。
3、shell,php,perl,python特点及区别
4、全局变量、普通变量的定义规范,定义方法
5、特殊变量,位置变量,进程状态变量
6、变量的字串知识
7、变量的数值计算:
(()),let,expr,bc(小数awk),$[]
预习:
1、条件测试
2、if语句
3、case语句
4、while循环

 

 

条件测试与比较

条件测试语法格式

语法格式1:  test <测试表达式>
语法格式2:  [ <测试表达式> ]
语法格式3:    [[ <测试表达式> ]]

 

man test

 

1.test

test判断文件或者目录

test -f /etc/hosts && echo 1||echo 0

1

test -f /etc && echo 1||echo 0

0

test -d /etc && echo 1||echo 0

1

 

取反

test ! -f /etc && echo 1||echo 0

1

 

判断字符串是否为0

test -z "oldboy"&&echo 1||echo 0

0

test -z ""&&echo 1||echo 0

1

 

2.[ ]

判断文件或者目录

[ -f ] -f两端必须都有空格

[ -z "oldboy" ] && echo 1||echo 0

0

[ -z "" ] && echo 1||echo 0

1

[ -f /etc/hosts ] && echo 1||echo 0

1

[ -f /etc ] && echo 1||echo 0

0

 

3.[[]]

判断文件或者目录

[root@MySQL ~]# [[ -f "/etc/hosts" ]]&&echo 1||echo 0

1

[root@MySQL ~]# [[ -e "/etc/hosts" ]]&&echo 1||echo 0

1

[root@MySQL ~]# [[ ! -e "/etc/hosts" ]]&&echo 1||echo 0

0

 

4.[]和[[]]的区别

[[ ]]         逻辑符号用&& 或者 ||

[ ]            逻辑符号用-a 或者 -o

 

 

[root@MySQL ~]# [[ -e "/etc/hosts" && -f /etc/hosts ]]&&echo 1||echo 0   
1
[root@MySQL ~]# [[ -e "/etc/hosts" || -f /etc/hosts ]]&&echo 1||echo 0  
1


[root@MySQL ~]# [ -e "/etc/hosts" || -f /etc/hosts ]&&echo 1||echo 0  
-bash: [: missing `]‘
-bash: -f: command not found


0
[root@MySQL ~]# [ -e "/etc/hosts" -o -f /etc/hosts ]&&echo 1||echo 0  
1
[root@MySQL ~]# [ -e "/etc/hosts" -a -f /etc/hosts ]&&echo 1||echo 0  
1

 

文件测试表达式

技术分享

 

-f 文件(普通文件)

[root@liwx ~]# [ -f oldboy ]&& echo 1

1

[root@liwx ~]# [ -f oldboy ]||1

 

-d 目录

[root@liwx ~]# [ -f oldboy1 ]||echo 1

1

[root@liwx ~]# [ -d oldboy1 ]||echo 1

[root@liwx ~]# [ -f oldboy1 ]&&echo 1||echo 0

0

 

-e 文件(只要是文件就可以)

[root@liwx ~]# [ -e oldboy1 ]&&echo 1||echo 0

1

 

-r 可读

-w 可写

-x 可执行

 

测试变量

文件

[root@liwx ~]# file1=/etc/services ;file2=/etc/rc.local

[root@liwx ~]# echo $file1

/etc/services

[root@liwx ~]# echo $file2

/etc/rc.local

[root@liwx ~]# [ -f "$file2" ] &&echo 1||echo 0

1

[root@liwx ~]# [ -f "$file1" ] &&echo 1||echo 0

1

[root@liwx ~]# [ -d "$file1" ] &&echo 1||echo 0

0

[root@liwx ~]# [ -e "$file1" ] &&echo 1||echo 0

1

 

目录

[root@liwx ~]# dir1=/etc

[root@liwx ~]# [ -d "$dir1" ] &&echo 1||echo 0

1

[root@liwx ~]# [ -e "$dir1" ] &&echo 1||echo 0

1

[root@liwx ~]# [ -w "$dir1" ] &&echo 1||echo 0

1

[root@liwx ~]# [ -x "$dir1" ] &&echo 1||echo 0

1

 

测试

#!/bin/sh

[ -f /tmp/oldboy.log ]||exit 5        #不存在就退出

cat /tmp/oldboy.log                    #存在就查看

 

多个条件

[root@MySQL 02]# [ -f "$file1" -a -f "$file2" ] &&echo 1||echo 0   
1
[root@MySQL 02]# [ -f "$file1" -o -f "$file2" ] &&echo 1||echo 0 
1
[root@MySQL 02]# [ -f "$file1" -a -f "$file2" ] &&echo 1||echo 0   
1
[root@MySQL 02]# [ ! -f "$file1" -a -f "$file2" ] &&echo 1||echo 0
0

 

多个命令

[root@MySQL 02]# sh f.sh 
[root@MySQL 02]# echo 123 >/tmp/oldboy.log
[root@MySQL 02]# sh f.sh 
123
1
[root@MySQL 02]# cat f.sh 
#!/bin/sh
[ -f /tmp/oldboy.log ]&&{
 cat /tmp/oldboy.log 
 echo 1
 exit
}

 

等于if语句

if [ -f /tmp/oldboy.log ];then

    cat /tmp/oldboy.log

    echo 1

    exit

fi

 

[ 3 -ne 3 ] ||{ echo ‘I am oldboy‘;echo "I am coming";exit 1; }

 

 

字符串测试表达式

字符串测试操作符的作用,比较两个字符串是否相同,字符串长度是否为0,字符串是否为NULL

技术分享

 

1.判断字符串是否为空

[root@mysql-2 scripts]# [ -n "abc" ]&&echo 1||echo 2

1

[root@mysql-2 scripts]# [ -n "" ]&&echo 1||echo 2

2

[root@mysql-2 scripts]# [ -z "abc" ]&&echo 1||echo 2

2

[root@mysql-2 scripts]# [ -z "" ]&&echo 1||echo 2

1

 

 

[root@MySQL ~]# sed -n ‘30,31p‘ /etc/init.d/network
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 6

 

 

[root@MySQL ~]# [ "abc" != "abc " ]&&echo 1||echo 0    
1
[root@MySQL ~]# [ "abc" != "abc" ]&&echo 1||echo 0 
0

 


[root@MySQL ~]# test="abc"
[root@MySQL ~]# [ "$test" != "abc" ]&&echo 1||echo 0   
0
[root@MySQL ~]# test1=abd
[root@MySQL ~]# [ "$test" = "$test1" ]&&echo 1||echo 0    
0
[root@MySQL ~]# [ "${#test}" = "${#test1}" ]&&echo 1||echo 0
1

 

多个字符串

 

整数二元比较操作符

 

技术分享

 

-eq        ==或=    equal

-ne        !=        not equal

-gt        >        greater than

-ge        <=        greater equal

-lt        <        less than

-le        <=        less equal

 

 

不推荐用=><符号,符号需要转译

[root@liwx ~]# [ 2 > 1 ]&&echo 1||echo 0

1

[root@liwx ~]# [ 2 > 3 ]&&echo 1||echo 0

1

[root@liwx ~]# [ 2 \> 3 ]&&echo 1||echo 0

0

 

用-gt

[root@liwx ~]# [ 2 -gt 3 ]&&echo 1||echo 0

0

[root@liwx ~]# [ 2 -lt 3 ]&&echo 1||echo 0

1

[root@liwx ~]# [ 2 -eq 3 ]&&echo 1||echo 0

0

 

[[]]双中括号 可以用<>=

[root@liwx ~]# [[ 2 > 3 ]]&&echo 1||echo 0

0

 

整数比较,推荐的方法

[ $num1 -eq $num2 ]    #注意空格,和比较符号

(($num1>$num2))        #无需空格,常规数学比较符号

技术分享

 

 

逻辑操作字符

技术分享

 

[]     [[]]

-a        &&        and        

-o        ||        或

!        !        非

 

[root@MySQL ~]# sed -n ‘87,90p‘ /etc/init.d/nfs  
        [ "$NFSD_MODULE" != "noload" -a -x /sbin/modprobe ] && {
                /sbin/modprobe nfsd
                [ -n "$RDMA_PORT" ] && /sbin/modprobe svcrdma
        }

 

 

利用条件表达式完成

比较两个整数的大小

[root@MySQL scripts]# cat cmp2.sh 
#!/bin/sh

 

#no.1 judge arg nums.

[ $# -ne 2 ]&&{

echo "USAGE:"$0" num1 num2"

exit 1

}

#no.2 judge if int.

expr $1 + 1 &>/dev/null

RETVAL1=$?

expr $2 + 1 &>/dev/null

RETVAL2=$?

 

[ $RETVAL1 -ne 0 -a $RETVAL2 -ne 0 ]&&{

echo "pls input two nums."

exit 2

}

[ $RETVAL1 -ne 0 ]&&{

echo "The first num is not int,pls input again."

exit 2

}

[ $RETVAL2 -ne 0 ]&&{

echo "The second num is not int,pls input again."

exit 3

}

 

#no.3 compare two int.

[ $1 -lt $2 ]&&{

echo "$1<$2"

exit 0

}

[ $1 -eq $2 ]&&{

echo "$1=$2"

exit 0

}

[ $1 -gt $2 ]&&{

echo "$1>$2"

exit 0

}

 

变量的三种输入方式:

1.定义            a=1

2.传参方式        $1

3.read交互式读入
[root@liwx scripts]# cat ad.sh

#!/bin/sh

read -t 5 -p "Pls input a character:" a

echo "your input is:$a"

 

多级菜单脚本

综合实例:打印选择菜单,一键安装Web服务:
[root@oldboy scripts]# sh menu.sh 
    1.[install lamp]
    2.[install lnmp]
    3.[exit]
    pls input the num you want:
要求:
1、当用户输入1时,输出"start installing lamp."然后执行/server/scripts/lamp.sh,脚本内容输出"lamp is installed"后退出脚本;
2、当用户输入2时,输出"start installing lnmp." 然后执行/server/scripts/lnmp.sh输出"lnmp is installed"后退出脚本;
3、当输入3时,退出当前菜单及脚本;
4、当输入任何其它字符,给出提示"Input error"后退出脚本。
5、要对执行的脚本进行相关条件判断,例如:脚本是否存在,是否可执行等

 

[root@MySQL scripts]# cat menu1.sh    
#!/bin/sh

#no.1 menu
cat <<EOF
    1.[install lamp]
    2.[install lnmp]
    3.[exit]
EOF
#no.2
read -t 20 -p " pls input the num you want:" num
[ "$num" != "1" -a  "$num" != "2" -a  "$num" != "3" ]&&{
 echo "Input error"
 exit
}
#no.3
[ $num -eq 1 ]&&{
 echo "install lamp"
 [ -f /server/scripts/lamp.sh ]&&\
 /bin/sh /server/scripts/lamp.sh
 exit
}
[ $num -eq 2 ]&&{
 echo "install lnmp"
[ -f /server/scripts/lnmp.sh ]&&\
 /bin/sh /server/scripts/lnmp.sh
 exit
}

[ $num -eq 3 ]&&{
 echo "bye!"
 exit
}

 

 

if条件句

单分支结构

语法:
if  [ 条件 ]
then
指令
fi

或者

if [条件];then

    指令

fi

技术分享

案例1

[root@liwx scripts]# cat bc.sh

#!/bin/sh

 

if [ -f /etc/hosts ];then

echo 1

fi

 

案例2

范例2:开发脚本判断系统剩余内存大小,如果低于100M就邮件报警,并且加入系统定时任务每3分钟执行一次检查。

 

配置mail

echo -e "set from=oldboy@163.com smtp=smtp.163.com\nset smtp-auth-user=oldboy smtp-auth-password=oldboy123 smtp-auth=login" >>/etc/mail.rc

 

 


#!/bin/bash
mem=`free -m|awk -F‘[ :]+‘ ‘NR==3 {print $4}‘`
if [ $mem -le 100 ];then
echo "内存不足可用内存为:${mem}M"|mail -s "内存警告" shmilyjinian@163.com
fi

 

[root@liwx scripts]# cat free.sh

#!/bin/sh

 

MEM=`free -m|awk ‘NR==3 {print $4}‘`

if [ $MEM -lt 2000 ];then

echo "The memory_$(date +%F-%R)_warning:: $MEM"

exit 1

fi

 

 

双分支结构

语法:
if  [ 条件 ]
then
指令

else

指令
fi

或者

if [条件];then

    指令

fi

 

 

 

 

范例1:用if双分支实现对nginx服务是否正常判断,使用进程数的方式判断,如果进程没起,把进程启动。

 

[root@lnmp ~]# cat check_web.sh 
#!/bin/sh
if [ `ps -ef|grep "nginx"|egrep -v "php-fpm|grep"|wc -l` -ge 2 ] 
then
   echo "Nginx is running."
else
   echo "Nginx is stopped."
   /application/nginx/sbin/nginx
fi

 

 

[root@lnmp ~]# ps -C nginx
  PID TTY          TIME CMD
10437 ?        00:00:00 nginx
10438 ?        00:00:00 nginx
10439 ?        00:00:00 nginx
10440 ?        00:00:00 nginx
10441 ?        00:00:00 nginx
10442 ?        00:00:00 nginx
10443 ?        00:00:00 nginx
10444 ?        00:00:00 nginx
10445 ?        00:00:00 nginx
10446 ?        00:00:00 nginx
10447 ?        00:00:00 nginx
[root@lnmp ~]# ps -C nginx --no-header

 

 

 

多分支结构

语法

if 条件1

then

     指令1

elif 条件2

then

     指令2

else

     指令3

fi

技术分享

 

 

范例3:使用if多分支语句、read及脚本传参方式如何实现2个整数比较大小?

[root@liwx scripts]# vim arg2.sh

 

#!/bin/sh

 

#no.1 judge arg nums.

[ $# -ne 2 ]&&{

echo "USAGE:"$0" num1 num2"

exit 1

}

#no.2 judge if int.

expr $1 + 1 &>/dev/null

RETVAL1=$?

expr $2 + 1 &>/dev/null

RETVAL2=$?

 

if [ $RETVAL1 -ne 0 -a $RETVAL2 -ne 0 ];then

echo "pls input two nums."

exit 1

fi

 

if [ $RETVAL1 -ne 0 ];then

echo "The first num is not int,pls input again."

exit 2

fi

 

if [ $RETVAL2 -ne 0 ];then

echo "The second num is not int,pls input again."

exit 3

fi

 

if [ $1 -lt $2 ]

then

echo "$1<$2"

exit 0

elif [ $1 -eq $2 ]

then

echo "$1=$2"

exit 0

else

echo "$1>$2"

fi

 

 

 

[root@MySQL 02]# cat if-judge2-by-arg.sh 
#!/bin/bash
a=$1
b=$2
#no.1 judge arg nums.
if [ $# -ne 2 ];then
        echo "USAGE:$0 arg1 arg2"
        exit 2
fi

#no.2 judge if int
expr $a + 1 &>/dev/null
RETVAL1=$?
expr $b + 1 &>/dev/null
RETVAL2=$?
if [ $RETVAL1 -ne 0 -a $RETVAL2 -ne 0 ];then
        echo "please input two int again"
        exit 3
fi

if [ $RETVAL1 -ne 0 ];then
        echo "The first num is not int,please input again"
        exit 4
fi

if [ $RETVAL2 -ne 0 ];then
        echo "The second num is not int,please input again"
        exit 5
fi

#no.3 compart two num.
if [ $a -lt $b ];then
        echo "$a<$b"
        exit
elif [ $a -eq $b ];then
        echo "$a=$b"
        exit
else
        echo "$a>$b"
fi


[root@MySQL 02]# cat if-judge2-by-read.sh    
#!/bin/bash
read -p "pls input two num:" a b
#no.1 judge read.
[ -z "$a" ]||[ -z "$b" ] && {                
    echo "pls input two num agagin"
    exit 1
}

#no.2 judge if int
expr $a + 1 &>/dev/null
RETVAL1=$?
expr $b + 1 &>/dev/null
RETVAL2=$?
if [ $RETVAL1 -ne 0 -a $RETVAL2 -ne 0 ];then
        echo "please input two int again"
        exit 3
fi

if [ $RETVAL1 -ne 0 ];then
        echo "The first num is not int,please input again"
        exit 4
fi

if [ $RETVAL2 -ne 0 ];then
        echo "The second num is not int,please input again"
        exit 5
fi

#no.3 compart two num.
if [ $a -lt $b ];then
        echo "$a<$b"
        exit
elif [ $a -eq $b ];then
        echo "$a=$b"
        exit
else
        echo "$a>$b"
fi

 

 

 

范例4:实现通过传参的方式往/etc/user.conf里添加用户,具体要求如下:
1)命令用法:
USAGE: sh adduser {-add|-del|-search} username 
2)传参要求:
如果参数为-add时,表示添加后面接的用户名,
如果参数为-del时,表示删除后面接的用户名,
如果参数为-search时,表示查找后面接的用户名,
3)如果有同名的用户则不能添加,没有对应用户则无需删除,查找到用户以及没有用户时给出明确提示。
4)/etc/user.conf不能被所有外部用户直接删除及修改

 

北京-郭雨明 20:12:05

#!/bin/bash

username=$2

file=/etc/user.conf

if [ $# -ne 2 ];then

    echo "USAGE:$0 {-add|-del|-search} username"

    exit 2

fi

case "$1" in

-add|--add)

    if [ `grep "\<$username\>" /etc/user.conf |wc -l` -ne 0 ];then

        echo "user exist"

    else

        echo $username >>$file

    fi

    ;;

-del|--del)

    if [ `grep "\<$username\>" /etc/user.conf |wc -l` -eq 0 ];then

        echo "user not exist"

    else

        sed -i "/\<$username\>/d" $file

    fi

    ;;

-search|--search)

    if [ `sed -n "/\<$username\>/p" $file |wc -l` -eq 0 ];then

        echo "no such user"

    else

        echo $username

    fi

    ;;

*)

    echo "error arg"

    exit

esac

 

企业案例:写网络服务rsync的系统启动脚本
范例3 :利用if语句开发类似系统启动rsync服务的脚本
(可参考系统的rpcbind/nfs/crond脚本)!
例如:/etc/init.d/rsyncd {start|stop|restart}
测试用例:
[root@oldboy 04]# touch /etc/rsyncd.conf
[root@oldboy 04]# rsync --daemon
[root@oldboy 04]# lsof -i :873
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
rsync   14085 root    4u  IPv4 555582      0t0  TCP *:873 (LISTEN)
rsync   14085 root    5u  IPv6 555583      0t0  TCP *:873 (LISTEN)

#!/bin/sh

 

[ -f /etc/rsyncd.conf ] || {

echo

}exit

if [ $# -ne 1 ]

then

echo "USAGE: /etc/init.d/$0 {start|stop|restart}"

exit 1

fi

 

 

[root@mysql ~]# cat rsync.sh 
#!/bin/sh

[ -f /etc/rsyncd.conf ]&&touch /etc/rsyncd.conf&&\
if [ $# -ne 1 ]
   then
    echo "USAGE: /etc/init.d/$0 {start|stop|restart}"
    exit 1
fi
 
if [ "$1" == "start" ]
   then
   rsync --daemon
   echo "rsync is running"
   exit 
fi

if [ "$1" == "stop" ]
   then
   pkill rsync
   echo "rsync is stopping"
   exit 
fi
if [ "$1" == "restart" ]
   then
    pkill rsync &&\
    rsync --daemon
   echo "rsync is restart"
   exit 
fi

 


范例4:开发生产mysql多实例启动的脚本(以前的课程内容)
(1)mysql多实例的启动:
[root@oldboy 3306]# /data/3306/mysql start
Starting MySQL...
[root@oldboy 3306]# /bin/sh /application/mysql/bin/mysqld_safe --defaults-file=/data/3306/my.cnf 2>&1 > /dev/null &
[1] 31898
[root@oldboy 3306]# netstat -lnt|grep 330                                          tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN
(2)mysql多实例的停止:
[root@oldboy 3306]# /data/3306/mysql stop
Stoping MySQL...
mysqladmin -u root -poldboy -S /data/3306/mysql.sock shutdown
利用if语句开发mysql多实例启动脚本。

 

武汉-谢迪六组组长(397731124) 9:51:13

[root@mysql ~]# cat mysql.sh

#!/bin/sh

 

if [ $# -ne 1 ]

then

echo "/data/3306/$0 [start|stop]"

exit

fi

if [ "$1" == "start" ]

then

/bin/sh /application/mysql/bin/mysqld_safe --defaults-file=/data/3306/my.cnf 2>&1 > /dev/null &

echo "Starting MySQL...."

exit

fi

if [ "$1" == "stop" ]

then

mysqladmin -u root -poldboy123 -S /data/3306/mysql.sock shutdown

echo "Stoping MySQL..."

exit

fi

 

判断字符串是否为整数

法1

expr $a + $b +1 &>/dev/null

法2

[ -n "`echo 123`"|sed ‘s###g‘ ]

[root@MySQL 3306]# [ -n "`echo "123"|sed ‘s/[0-9]//g‘`" ] && echo char||echo int      
int
[root@MySQL 3306]# [ -n "`echo "oldboy123"|sed ‘s/[0-9]//g‘`" ] && echo char||echo int
char

法3

 

法4

[root@MySQL 3306]# [ -n "$num" -a "$num" = "${num//[^0-9]/}" ] && echo "it is num"||echo "fei num"

 

法5

[root@MySQL 3306]# [[ 123 =~ ^[0-9]+$ ]] &&echo int ||echo char  
int
[root@MySQL 3306]# [[ oldboy123 =~ ^[0-9]+$ ]] &&echo int ||echo char   
char

 

 

监控DB服务是否正常,不低于5种思路

方法:web和db共同方法
1、端口
   本地:netstat,ss,lsof
   远程:telnet,nmap,nc
2、 进程(本地)
====================================
3、wget/curl(http方式,判断根据返回值或者返回内容)。
4、header(http),(http方式,根据状态码判断)
5、数据库特有,通过mysql客户端连接连接,根据返回值或者返回内容。

 

 

 

查看远端的端口是否通畅3个简单实用案例!
http://oldboy.blog.51cto.com/2561410/942530
2、本地进程数
3、header(http code) curl -I web地址返回200就OK。
掌握技术思想比解决问题本身更重要
http://oldboy.blog.51cto.com/2561410/1196298
4、URL(wget,curl)web地址,模拟用户的方式。
5、php,java写一个程序,模拟用户的方式监控(让开发提供)。

 

 

 

 

 

http://oldboy.blog.51cto.com/2561410/942530

#注意脚本名不要写成mysql.sh

grep过滤mysql的时候进程会多

 

4、通过php/java程序url方式监控MySQL(老男孩老师推荐)
   最接近模拟用户访问,效果最好。报警的最佳方式不是服务是否开启了,而是网站的用户是否还访问正常。

 

参考/etc/init.d/rpcbind

 

 

1.端口

本地:netstat,ss,lsof

远程;telnet,nmap,nc

大全讲解:
[root@shell 03]# cat check_db.sh 
#!/bin/sh
if [ "`netstat -lnt|grep 3306|awk -F "[ :]+" ‘{print $5}‘`" = "3306" ]
#cuo-if [ `netstat -lnt|grep 3306|awk -F "[ :]+" ‘{print $5}‘` -eq 3306 ]
#if [ `ps -ef|grep mysql|grep -v grep|wc -l` -gt 0 ]
#if [ `nc -w 2  10.0.0.7 3306 &>/dev/null&&echo ok|grep ok|wc -l` -gt 0 ]
#if [ `nmap 10.0.0.7 -p 3306 2>/dev/null|grep open|wc -l` -gt 0 ]
#if [ `netstat -lntup|grep mysqld|wc -l` -gt 0 ]
#if [ `lsof -i tcp:3306|wc -l` -gt 0 ]
  then
     echo "MySQL is Running."
else
     echo "MySQL is Stopped."
     /data/3306/mysql start
fi

 

 

本地,端口,进程

[root@MySQL scripts]# cat check_db01.sh 
#!/bin/sh
port=`ps -ef|grep mysql|grep -v grep|wc -l`
#port=`lsof -i:3307|grep mysql|wc -l`
#port=`ss -lntup|grep mysql|wc -l`
#port=`netstat -lntup|grep mysql|wc -l`
if [ $port -ne 2 ];then
   echo "MySQL is not running"
else
   echo "MySQL is running"
fi

 

远程

监控nginx

#!/bin/sh

 

#prot=`ss -lntup|grep nginx|wc -l`

prot=`lsof -i:80|grep nginx|wc -l`

prot1=`nmap 10.0.0.5 -p 3307|grep open|wc -l`

 

 

#if [ $prot -ne 1 ];then

if [ $prot -ne 2 ];then

echo "nginx is not runnint"

else

echo "nginx is runnint"

fi

 

 

 

 

wget

[root@MySQL scripts]# cat check_web01.sh 
port=`wget -T 10 --spider -t 2 技术分享技术分享http://10.0.0.5 &>/dev/null`
if [ $? -ne 0 ];then
#if [ $port -ne 1 ];then
   echo "httpd is not running"
else
   echo "httpd is running"
fi

 

curl

[root@MySQL scripts]# curl -I -s -w "%{http_code}\n" 10.0.0.5 -o /dev/null 
200

[root@MySQL scripts]# cat check_web01.sh 
port=`curl -s -I 10.0.0.5|head -1|grep "\b200\b"|wc -l`
#port=`curl --connect-timeout 5 技术分享技术分享http://10.0.0.5 &>/dev/null`
#port=`wget -T 10 --spider -t 2 技术分享技术分享http://10.0.0.5 &>/dev/null`
#if [  $port -ne 1 ];then
#if [ $port -ne 1 ];then
if [ "`curl -I -s -w "%{http_code}\n" 10.0.0.5 -o /dev/null`" != "200" ]
then
   echo "httpd is not running"
else
   echo "httpd is running"
fi

 

 

使用grep实现精确过滤的五种方法

http://oldboy.blog.51cto.com/2561410/1685520

[root@MySQL scripts]# cat oldboy.log       
200
0200
2000
[root@MySQL scripts]# grep "\b200\b" oldboy.log 
200
[root@MySQL scripts]# grep -w "200" oldboy.log                  
200
[root@MySQL scripts]# grep -x "200" oldboy.log                  
200
[root@MySQL scripts]# grep "^200$" oldboy.log 
200

 

 

 

 

小结

1.条件表达式

文件,字符串,整数

2.if语句

取值判断

3,函数

 

 

函数

 

shell函数

1.使用函数的优势

函数的作用,把程序里多次调用相同的代码部分定义成一份

1.把相同程序段定义成函数,可以减少整个程序的代码量

2.增加程序的可读,易读性.

3.可以实现程序功能模块化,不同的程序使用函数模块化.

强调:对于shell来说,linux系统的2000多个命令都可以说是shell函数

 

语法

函数名(){

指令..

return

}

 

示例

[root@liwx 1]# vim hanshu.sh

liwx(){

echo "i am liwenxue!!"

}

 

xiaoming(){

echo "i am guoyuming"

}

liwx

xiaoming

 

[root@liwx 1]# sh hanshu.sh

i am liwenxue!!

i am guoyuming

 

 

2.函数的传参

函数名 参数1 参数2

技术分享

 

[root@liwx 1]# vim hanshu.sh

who(){

echo "i am $1"

}

who oldboy

 

[root@liwx 1]# sh hanshu.sh

i am oldboy

 

[root@liwx 1]# vim hanshu1.sh

who(){

echo "i am $1"

}

who $1

[root@liwx 1]# sh hanshu.sh liwx

i am liwx

 

3.检查网站是否正常

范例4:函数传参转成脚本命令行传参,对任意指定URL判断是否异常

法1

[root@MySQL scripts]# cat check_weburl.sh

#!/bin/sh
usage(){
 echo "USAGE:$0 arg"
 exit 1
}

check_web(){
curl -s $1 &>/dev/null
if [ $? -eq 0 ]
 then
    echo "$1 web is ok"
else 
    echo "$1 web is no"
fi
}
main(){
  if [ $# -ne 1 ]
  then
   usage
  fi
  check_web $1
}
main $*

 

法2

[root@MySQL scripts]# cat func02.sh 
#!/bin/sh
check_url(){
wget -T 10 --spider -t 2 $1 &>/dev/null
if [ $? -eq 0 ]
then
   echo "$1 is ok."
else
   echo "$1 is no."
fi
}
check_url $1

 

法3

#!/bin/sh
num=`curl -I -s -w "%{http_code}" $1 -o /dev/null`
url(){
if [ "$num" != "200" ];then
   echo "the $1 is worng"
  else
   echo "the $1 is right"
fi 
}
url $1

 

 

case语句

case就是一个多分支的if语句

语法

case "字符串变量" in 
    值1) 指令1...
;;
    值2) 指令2...
;;
    *) 指令...
esac

 

技术分享

 

技术分享

 

 

 

 

1.判断数字


如果用户输入1或2或3,则输出对应输入的数字,如果是其他
内容,返回不正确,退出。

 

老师的方法

[root@MySQL scripts]# cat case01.sh 
read -p "Please input a number:" ans 
case "$ans" in
1)
    echo  "the num you input is 1"
;;
2)
    echo "the num you input is 2"
;;
[3-9])
echo "the num you input is $ans"
;;
*)
    echo "the num you input must be less 9."
    exit;
esac

 

法2

[root@MySQL scripts]# cat if-re-case.sh 
#!/bin/sh
read -p "please input a number:" ans
if [ $ans -eq 1 ];then
        echo "the num you input is 1" 
elif [ $ans -eq 2 ];then
        echo "the num you input is 2" 
elif [ $ans -ge 3 -a $ans -le 9 ];then #<==此处也可以用正则,双中括号。
        echo "the num you input is $ans" 
else
        echo "the num you input must be less 9."
        exit
fi

 

[root@liwx 1]# vim case1.sh

 

case "$1" in

1)

echo print $1

;;

2)

echo print $1

;;

3)

echo print $1

;;

*)

echo print error

esac

 

2.打印水果菜单


1.apple
2.pear
3.banana
4.cherry
当用户选择水果的时候,打印告诉它选择的水果是什么,并给水果单词加上一种颜色。
要求用case语句实现。

 

#!/bin/sh
RED_COLOR=‘\E[1;31m‘
GREEN_COLOR=‘\E[1;32m‘
YELLOW_COLOR=‘\E[1;33m‘
BLUE_COLOR=‘\E[1;34m‘
RES=‘\E[0m‘
echo -e "$RED_COLOR oldboy $RES"
echo -e "$YELLOW_COLOR gongjie $RES"

[root@liwx 1]# vim color.sh

 

#!/bin/sh

RED_COLOR=‘\E[1;31m‘

GREEN_COLOR=‘\E[1;32m‘

YELLOW_COLOR=‘\E[1;33m‘

BLUE_COLOR=‘\E[1;34m‘

RES=‘\E[0m‘

#echo -e "$RED_COLOR oldboy $RES"

#echo -e "$YELLOW_COLOR gongjie $RES"

 

 

cat <<EOF

1.apple

2.pear

3.banana

4.cherry

q.quit

EOF

 

while true

do

read -p "please in put [1-4]:" a

 

case "$a" in

1)

echo -e "$GREEN_COLOR apple $RES"

;;

2)

echo -e "$YELLOW_COLOR pear $RES"

;;

3)

echo -e "$YELLOW_COLOR banana $RES"

;;

4)

echo -e "$RED_COLOR cherry $RES"

;;

q)

exit

;;

*)

echo "print [1-4]"

esac

done

 

 

老师的方法

 

[root@MySQL scripts]# cat case04.sh 
#!/bin/sh
add(){
RED_COLOR=‘\E[1;31m‘
GREEN_COLOR=‘\E[1;32m‘
YELLOW_COLOR=‘\E[1;33m‘
BLUE_COLOR=‘\E[1;34m‘
FLASH_COLOR=‘\33[5m‘
RES=‘\E[0m‘
case "$1" in
  red|RED)
         echo -e "$RED_COLOR $2 $RES"
         ;;
  green|GREEN)
         echo -e "$GREEN_COLOR $2 $RES"
         ;;
  yellow|YELLOW)
         echo -e "$YELLOW_COLOR $2 $RES"
         ;;
  blue|BLUE)
         echo -e "$BLUE_COLOR $2 $RES"
         ;;
         *)
         echo "plu use:{red|green|yellow|blue} {chars}"
         exit
esac
}

menu(){
cat <<END
=================
1.apple
2.pear
3.banana
4.cherry
5.exit
==================
END
}

fruit(){
read -p "pls input the fruit your like:" fruit
case "$fruit" in
    1)
      add red apple
    ;;
    2)
      add green pear
    ;; 
    3)
      add yellow banana
    ;;
    4)
      add blue cherry
    ;;
    5)
      exit
    ;;

    *)
      echo "pls select right num:{1|2|3|4}"
      exit
esac
}

main(){
 while true
 do
  menu
  fruit
 done
}
main

 

3.配置Nginx的启动脚本

已知nginx管理命令为:
启动:
/application/nginx/sbin/nginx
停止:
/application/nginx/sbin/nginx -s stop
重新加载:
/application/nginx/sbin/nginx -s reload
请用case脚本模拟nginx服务启动关闭:
/etc/init.d/nginx {start|stop|restart|reload} 
并实现可通过chkconfig管理。

 

 

[root@lnmp init.d]# cat nginx 
#!/bin/sh
# chkconfig: 2345 54 65
# description: Stop/Start nginx scripts

[ -f /etc/init.d/functions ] && . /etc/init.d/functions
nginx="/application/nginx/sbin/nginx"
prog="nginx"
RETVAL=0
start(){
   if [ ! -f /var/lock/subsys/$prog  ];then
     $nginx && RETVAL=$?
   else
      echo "Nginx is running."
      exit
   fi
   if [ $RETVAL -eq 0 ];then
      touch /var/lock/subsys/$prog
      action "Starting nginx" /bin/true
   else
      action "Starting nginx" /bin/false
   fi
   return $RETVAL
}
stop(){
   if [ -f /var/lock/subsys/$prog  ];then
     $nginx -s stop && RETVAL=$?
   else
      echo "Nginx is stopped."
      exit
   fi
   if [ $RETVAL -eq 0 ];then
      rm -f /var/lock/subsys/$prog
      action "Stopping nginx" /bin/true
   else
      action "Stopping nginx" /bin/false
   fi
   return $RETVAL
}
reload(){
   if [ -f /var/lock/subsys/$prog  ];then
     $nginx -s reload && RETVAL=$?
   else
      echo "Nginx is stopped."
      exit
   fi
    if [ $RETVAL -eq 0 ];then
      action "Reloading nginx" /bin/true
   else
      action "Reloading nginx" /bin/false
   fi
   return $RETVAL
}
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        stop
        start
        ;;
  reload)
        reload
        ;;
      *)
        echo "USAGE:$0 {start|stop|restart|reload}"
esac
exit $RETVAL

 

 

 

 

 

企业案例:开发mysql多实例启动脚本:
已知mysql多实例启动命令为:
mysqld_safe --defaults-file=/data/3306/my.cnf &
停止命令为:
mysqladmin -u root -poldboy123 -S /data/3306/mysql.sock shutdown
请完成mysql单实例或多实例启动启动脚本的编写
要求:用函数、case语句等实现。(15分钟)

 

系统标杆脚本

技术分享

 

/etc/init.d/functions
http://www.cnblogs.com/image-eye/archive/2011/10/26/2220405.html 

/etc/rc.d/rc.sysinit
/etc/init.d/nfs
/etc/init.d/rpcbind
/etc/init.d/httpd

 

 

 

 

while条件句

语法

while 条件

    do

    指令....

done

 

一直循环,死循环

while true

do

uptime

sleep 2

done

 

usleep 1000000(微秒)=sleep 1

 

while读文件的方式

拓展:while按行读文件的方式:
方式1:
exec <FILE
sum=0
while read line
do
    cmd
done
方式2:
cat ${FILE_PATH} | while read line
do
    cmd
done
方式3:
while read line
do
    cmd
done<FILE

 

例子

[root@MySQL scripts]# cat sum-while.sh 
sum=0
while read line
do
   i=`echo $line|awk ‘{print $10}‘`
   expr $i + 1 &>/dev/null
   [ $? -ne 0 ] && continue    #continue退出当次循环
   ((sum+=value))
done<access_2010-12-8.log 
echo $sum

 

法2

技术分享

 

while循环小结

  1. while循环的特长,执行守护进程,希望循环不退出持续执行的情况,用于频率小于1分钟循环处理,其他的while循环几乎都可以
  2. case语句可以用if语句替换一般在系统启动脚本传入少量固定规则字符串,用case语句,其他普通判断多用if
  3. 一句话,fi,for语句最常用,其次while(守护进程),case(服务启动脚本)

 

 

各个语句使用场景

条件表达式        简短的判断(文件是否存在,字符串是否为空等)

if                取值判断,不同值数量较少的情况.

while            守护进程无限循环(sleep)

case            服务启动脚本,菜单

for             正常的循环处理,最常用

函数             逻辑清晰,减少重复语句.

 

 

防止脚本执行中断的方法:


1)sh while_01.sh &
2)nohup /server/scripts/uptime.sh &
3)screen,保持会话,总结此命令

后台进程管理

 

技术分享

 

TOP

技术分享

 

top,ps,

 

 

●进程管理:(16个)总结这些命令
bg:后台运行 
fg:挂起程序 
jobs:显示后台程序 
kill,killall,pkill:杀掉进程
crontab:设置定时 
ps:查看进程 
pstree:显示进程状态树
top:显示进程 
nice:改变优先权 
nohup:用户退出系统之后继续工作
pgrep:查找匹配条件的进程 
strace:跟踪一个进程的系统调用情况
ltrace:跟踪进程调用库函数的情况 
vmstat:报告虚拟内存统计信息

 

90)网站访问慢的案例
linux java/http/php中某一个进程占用CPU很高。
解决案例:
top -p 32311
strace -p 32311
案例文档:
技术分享技术分享http://blog.linuxeye.com/343.html
技术分享技术分享http://www.tuicool.com/articles/YFVbia
技术分享技术分享http://blog.sina.com.cn/s/blog_48eef8410101fl4p.html

 

ps使用的技巧

995.查看进程按内存从大到小排列
ps -e  -o "%C  : %p : %z : %a"|sort -k5 -nr|head -10
老男孩老师提示:
CODE   NORMAL   HEADER
%C     pcpu     %CPU
%a     args     COMMAND
%p     pid      PID
%z     vsz      VSZ
更多: ......

996.怎样知道某个进程在哪个CPU上运行?
ps -eo pid,args,psr
[root@oldboy ~]# ps -eo pid,args,psr
  PID COMMAND                     PSR
    1 init [3]                      2
    2 [migration/0]                 0
    3 [ksoftirqd/0]                 0
    4 [watchdog/0]                  0
    5 [migration/1]                 1
    6 [ksoftirqd/1]                 1
    7 [watchdog/1]                  1

997.按cpu利用率从大到小排列
ps -e  -o "%C  : %p : %z : %a"|sort  -nr
老-男孩老师提示:见999


998.查看进程按内存从大到小排列
ps -e  -o "%C  : %p : %z : %a"|sort -k5 -nr|head -10
老男孩老师提示:
CODE   NORMAL   HEADER
%C     pcpu     %CPU
%a     args     COMMAND
%p     pid      PID
%z     vsz      VSZ

更多:
AIX FORMAT DESCRIPTORS
This ps supports AIX format descriptors, which work somewhat like the formatting
codes of printf(1) and printf(3). For example, the normal default output can be
produced with this:  ps -eo "%p %y %x %c". The NORMAL codes are described in the
next section.

CODE   NORMAL   HEADER
%C     pcpu     %CPU
%G     group    GROUP
%P     ppid     PPID
%U     user     USER
%a     args     COMMAND
%c     comm     COMMAND
%g     rgroup   RGROUP
%n     nice     NI
%p     pid      PID
%r     pgid     PGID
%t     etime    ELAPSED
%u     ruser    RUSER
%x     time     TIME
%y     tty      TTY
%z     vsz      VSZ

999.查进程已经运行了多长时间 
ps -eo "%p %c %t"
[root@oldboy ~]# ps -eo pid,cmd,etime
  PID CMD                             ELAPSED
    1 init [3]                    207-05:44:13
    2 [migration/0]               207-05:44:12
    3 [ksoftirqd/0]               207-05:44:12

 

范例2:通过while语句计算从1加到100之和(请用1+2+3..的方法)

法1

#!/bin/bash
i=0
while [ $i -ne 100 ]
 do
        i=$(($i+1))

done
echo $i

2
#!/bin/sh

i=1
sum=0
while ((i<101))
 do
     ((sum = sum + i))
      ((i++))
done
echo $sum

3

#!/bin/bash
i=1
sum=0
while [ $i -lt 101 ]
do
    let "sum=sum+i"
    let "i++"
done
echo $sum

 

分析日志,封掉DOS攻击

技术分享

 

 

课后作业:19:38 2015/8/18
1、if语句
3、函数
4、case语句
5、while语句基础
预习:
while
for
shell数组
trap信号及跳板机

shell必会19道 本周四下午 14:00
http://oldboy.blog.51cto.com/2561410/1632876

 

 

for循环

语法

for 变量名 in 变量取值列表

do

    指令

done

 

for 男人 in 世界
do
    if [ 有房 ] && [有车] && [存款] && [会做家务] && [帅气] && [温柔] && [体贴] && [逛街买东西];then
        echo "我喜欢"
    else
        rm -f 男人
    fi
done

 

技术分享

 

[root@liwx scripts]# vim for1.sh

 

for num in `seq 10`

do

echo $num

done

 

[root@liwx scripts]# sh for1.sh

1

2

3

4

5

6

7

8

9

10

 

范例2:获取当前目录下的目录或文件名作为变量列表打印输出

[root@liwx scripts]# cat for3.sh

#!/bin/sh

 

for n in `ls`

do

if [ -d $n ];then

echo "this is dir $n"

else

echo "this is file $n"

fi

done

 

[root@liwx scripts]# sh for3.sh

this is dir 1

this is file 2.sh

this is file ab.sh

 

批量改名

http://oldboy.blog.51cto.com/2561410/711342

mkdir /oldboy

cd /oldboy

touch stu_102999_{1..5}_finished.jpg


法1

[root@MySQL oldboy]# rename "_finished" "" *.jpg
[root@MySQL oldboy]# ls -l
总用量 4
-rw-r--r-- 1 root root 76 8月  18 22:23 for3.sh
-rw-r--r-- 1 root root  0 8月  18 22:24 stu_102999_1.jpg
-rw-r--r-- 1 root root  0 8月  18 22:24 stu_102999_2.jpg
-rw-r--r-- 1 root root  0 8月  18 22:24 stu_102999_3.jpg
-rw-r--r-- 1 root root  0 8月  18 22:24 stu_102999_4.jpg
-rw-r--r-- 1 root root  0 8月  18 22:24 stu_102999_5.jpg

 

法2

[root@MySQL oldboy]# cat for3.sh 
for file in `ls *.jpg`
do
  mv $file `echo $file|sed ‘s#_finished##g‘`
done

 

 

 

 

分库备份的脚本

[root@MySQL scripts]# cat bak_by_db.sh

#!/bin/sh

MYUSER=root

MYPASS=oldboy123

SOCKET=/data/3306/mysql.sock

MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"

MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"

BAKPATH="/server/backup/$(date +%F)"

[ ! -d $BAKPATH ] && mkdir -p $BAKPATH

 

for dbname in `$MYCMD -e ‘show databases;‘|sed ‘1d‘|grep -v "_schema"`

do

$MYDUMP -B -x --events $dbname|gzip >$BAKPATH/${dbname}.sql.gz

if [ $? -eq 0 ];then

echo "$dbname" >>$BAKPATH/${dbname}.log

fi

done

 

 

分库分表备份

#!/bin/sh

MYUSER=root

MYPASS=liwx123

SOCKET=/data/3306/mysql.sock

MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"

MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"

BAKPATH="/server/backup/$(date +%F)"

[ ! -d $BAKPATH ] && mkdir -p $BAKPATH

 

for dbname in `$MYCMD -e ‘show databases;‘|sed ‘1d‘|grep -v "_schema"`

do

for tabname in `$MYCMD -e "use $dbname;show tables;"|sed ‘1d‘`

do

$MYDUMP -x --events ${dbname} ${tabname}|gzip >$BAKPATH/${dbname}_${tabname}.sql.gz

if [ $? -eq 0 ];then

echo "${dbname}_${tabname}" >>$BAKPATH/${dbname}.${tabname}.log

fi

done

done

 

 

设置开机自启动

for n in `chkconfig --list|grep ‘3:on‘|awk ‘{print $1}‘|egrep -v "crond|network|sshd|rsyslog"`;do chkconfig $n off;done

 

 

输出序列的方法

[root@liwx db]# seq 1 5

1

2

3

4

5

 

[root@liwx db]# echo {a..z}

a b c d e f g h i j k l m n o p q r s t u v w x y z

 

 

for c语言循环

2.C语言型for循环结构
语法:
for((exp1; exp2; exp3))
do
   指令...
done

 

例:for和while对比
[root@www scripts]# cat for03.sh     
for ((i=1;i<=5;i++))
do
    echo $i
done

i=1
while ((i<=5))
do
   echo $i
   ((i++))
done

 

 

#sum=0

#!/bin/sh

 

 

计算1+2+3+..100

for ((i=1;i<=100;i++))

do

((sum+=$i))

done

echo $sum

 

 

求和尽量选择公式

echo (((1+100) * 100/2))

[root@oldboy scripts]# echo $(( (1+100) * 100/2 ))
5050
[root@oldboy scripts]# echo $(( (1+1000000) * 1000000/2 ))
500000500000

 

 

跳出循环的方法

break         跳出循环

continue         退出当次循环

exit            退出shell

 

 

break,continue,exit区别的示例

[root@liwx for]# vim for5.sh

 

for((i=0; i<=5; i++))

do

if [ $i -eq 3 ] ;then

#continue;

#break;

exit

fi

echo $i

done

echo "ok"

 

[root@sql ~]# sh cee.sh --continue
0
1
2
4
5
ok
[root@sql ~]# sh cee.sh  -----exit
0
1
2
[root@sql ~]# sh cee.sh ------break
0
1
2
ok

 

 

成产范例

1.配置多个别名IP

开发shell脚本实现给服务器临时配置多个别名IP,并可以随时撤销配置的所有IP。IP地址为:10.0.2.1-10.0.2.16,其中10.0.2.10不能配置。
配置ip命令(ifconfig/ip)提示:
ifconfig eth0:0 10.0.2.10/24 up
ifconfig eth0:0 10.0.2.10/24 down
ip addr add 10.0.2.1/24 dev eth0:0
ip addr del 10.0.2.1/24 dev eth0:0

[root@liwx for]# vim for6.sh

#!/bin/sh

 

IP=10.0.2

for n in {1..16}

do

if [ $n -eq 10 ];then

continue;

fi

ip addr add $IP.$n/24 dev eth0:0

done

 

老师的方法

[root@MySQL scripts]# cat add_ip.sh 
#!/bin/sh
USAGE(){
if [ $# -ne 1 ];then
   echo "$0 {start|stop}"
   exit
fi
}

start(){
  for ip in `seq 16`
  do
   if [ $ip -eq 10 ];then
     continue
   fi
   ip addr add 10.0.2.$ip/24 dev eth0 label eth0:$ip
  done
}
stop(){
  for ip in `seq 16`
  do
   if [ $ip -eq 10 ];then
   continue
   fi
   ip addr del 10.0.2.$ip/24 dev eth0 label eth0:$ip
  done
}

main(){
  case "$1" in
   start)
      start
      ;;
   stop)
      stop
      ;;
    *)
      USAGE
  esac
}
main $*

 

 

2.批量改名

问题1:使用for循环在/oldboy目录下批量创建10个文件,名称依次为:
oldboy-1.html
oldboy-2.html
oldboy-3.html
......
oldboy-10.html

 

[root@liwx for]# vim for1.sh

 

#!/bin/sh

[ ! -d /oldboy ] && mkdir /oldboy

for n in {1..10}

do

touch /oldboy/oldboy-${n}.html

done

 


问题2:用for循环实现将以上文件名中的oldboy全部改成linux,并且扩展名改成大写。要求:for循环的循环体不能出现oldboy字符串。
参考:http://oldboy.blog.51cto.com/2561410/711342

 

[root@MySQL scripts]# cat k2.sh 
cd /oldboy
for n in `ls *.html`
do
  mv $n `echo $n|sed -r ‘s#^o.*y(.*)html#linux\1HTML#g‘`
done


问题3:批量创建10个系统帐号oldboy01-oldboy10并设置密码(密码不能相同)。
数字加0的思路:

http://oldboy.blog.51cto.com/2561410/788422

 

3.批量创建用户并设置随机密码


问题4:批量创建10个系统帐号oldboy01-oldboy10并设置密码(密码为随机8位字符串)。
不用for循环实现思路:

http://user.qzone.qq.com/49000448/blog/1422183723 

[root@MySQL scripts]# cat adduser.sh
for n in `seq -w 10`
do
   pass=`echo $RANDOM|md5sum|cut -c 2-9`
   useradd oldboy$n &&\
   echo $pass|passwd --stdin oldboy$n
   echo -e "oldboy$n \t $pass" >>/tmp/user.log
done


以上内容的视频讲解:
企业精品shell面试题案例及专家解答精讲
http://edu.51cto.com/course/course_id-1511.html

shell数组

简单的说,数组就是相同数据类型的元素按一定顺序排列的集合.

 

数组就是把有限个类型元素变量或数据用一个名字命名

 

语法

array=(1 2 3 4 5)

或者

array=(

1

2

3

4

5)

 

数组的定义方法

array=(value1 value2 value3)

 

1)打印数组的长度

array=(1 2 3)

echo ${#array[@]} 或者 echo ${#array[*]}

 

[root@liwx for]# array=(1 2 3)

[root@liwx for]# echo ${#array[@]}

3

[root@liwx for]# echo ${#array[*]}

3

 

2)打印数组元素

[root@liwx for]# echo ${array[0]}

1

[root@liwx for]# echo ${array[1]}

2

[root@liwx for]# echo ${array[2]}

3

[root@liwx for]# echo ${array[*]}

1 2 3

[root@liwx for]# echo ${array[@]}

1 2 3

 

 

 

 

[root@MySQL scripts]# cat arr01.sh 
array=(1 2 3)
for ((i=0;i<${#array[*]};i++))
do
   echo ${array[i]}
done
echo ============
for i in ${array[*]}
do
        echo $i
done

 

 

数组赋值

[root@test1 while]# array=(1 2 3)

[root@test1 while]# echo ${array[*]}

1 2 3

[root@test1 while]# echo ${#array[*]}

3

[root@test1 while]# array[3]=4

[root@test1 while]# echo ${#array[*]}

4

[root@test1 while]# echo ${array[*]}

1 2 3 4

[root@test1 while]# echo ${array[3]}

4

 

修改数组内的元素

[root@test1 while]# array[0]=liwx

[root@test1 while]# echo ${#array[*]}

4

[root@test1 while]# echo ${array[*]}

liwx 2 3 4

[root@test1 while]# echo ${array[0]}

liwx

 

 

 

删除赋值(删除单个值)

[root@test1 while]# unset array[0]

[root@test1 while]# echo ${array[*]}

2 3 4

 

删除整个数组

[root@test1 while]# unset array

[root@test1 while]# echo ${array[*]}

 

[root@test1 while]#

 

数组内容的截取和替换

截取

[root@test1 while]# array=(1 2 3 4 5)

[root@test1 while]# echo ${array[*]:2:3}

3 4 5

[root@test1 while]# echo ${array[*]:2}

3 4 5

[root@test1 while]# echo ${array[*]:1}

2 3 4 5

 

替换

[root@test1 while]# array=(1 2 3 4 5)

[root@test1 while]# echo ${array[*]:1}

2 3 4 5

[root@test1 while]# echo ${array[*]/2/liwx}

1 liwx 3 4 5

 

 

 

 

[root@liwx scripts]# vim arr2.sh

 

array=(

oldboy

zhangyue

zhangyang

)

 

for ((i=0;i<${#array[*]};i++))

do

echo "this is num $i,then content is ${array[$i]}"

done

echo ==================================================

echo "array len:${#array[*]}"

 

[root@liwx scripts]# sh arr2.sh

this is num 0,then content is oldboy

this is num 1,then content is zhangyue

this is num 2,then content is zhangyang

--------------------------

array len:3

 

 

 

动态数组

ls

[root@MySQL scripts]# cat array2.sh   
array=($(ls))
for ((i=0;i<${#array[*]};i++))
do
   echo ${array[i]}
done
echo ============
for i in ${array[*]}
do
        echo $i
done

 

 

 

检查多个网站地址是否正常 
要求:
1、shell数组方法实现,检测策略尽量模拟用户访问。
2、每10秒钟做一次所有的检测,无法访问的输出报警。
3、待检测的地址如下
http://www.etiantian.org
http://www.taobao.com
http://oldboy.blog.51cto.com
http://10.0.0.7

 

curl -I -s -w "%{http_code}\n" -o /dev/null www.baidu.com

wget -T 4 -q --spider ${url_list[$i]} >&/dev/null

 

curl -o /dev/null -s --connect-timeout 5 -w "%{http_code}\n" www.baidu.com

200

 

[root@lnmp02 bbs]# curl -o /dev/null -s --connect-timeout 5 -w "%{http_code}\n" bbs.etiantian.org

301

 

[root@MySQL scripts]# cat check_url.sh 
#!/bin/sh
. /etc/init.d/functions
url_list=(
  http://10.0.0.5
  http://www.baidu.com
  http://oldboy.blog.51cto.com
  http://10.0.0.19
)

check_url(){
  [ $# -ne 1 ] && exit 1
  
  curl -o /dev/null -s --connect-timeout 5 -w "%{http_code}\n" $1
}
main(){
for ((i=0;i<${#url_list[*]};i++))
do
    code=`check_url ${url_list[i]}`
    if [ "$code" != "200" -a "$code" != "301" ];then
       action "${url_list[i]}" /bin/false
    else
       action "${url_list[i]}" /bin/true
    fi
done
}
main $*

 

 

 

课后作业:19:38 2015/8/18
while
for
shell数组
预习:
shell的调试
.vimrc配置
trap信号及跳板机
kickstart无人值守批量安装
memcached服务

shell的调试

  1. 学习脚本开发规范
  2. 好的编码习惯

 

打游戏的思想

    (第一关,第二关,第三关)

专业的脚本

函数1

函数2

main

main $*

 

dos2unix

 

 

 

 

bash命令参数调试

sh [-nvx] test.sh

-n: 不会执行该脚本,仅查询脚本语法是否有问题,并给出错误提示

-v: 先打印,在执行,如有错误,也会提示

-x: 将执行结果输出

 

set [-nvx]

 

小结

 

 

 

.vimrc

  1. 自动加版权信息
  2. 自动补全括号等
  3. 自动缩进

 

1.10.5 .vimrc vim配置代码
" ~/.vimrc
" vim config file
" date 2008-09-05 
" Created by liwx
" liwx QQ:79441650

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 全局配置
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"关掉兼容模式
set nocompatible 

"设置历史记录步数
set history=4000

"开启文件类型判断插件
filetype plugin on
filetype indent on 

"当文件在外部被修改,自动更新该文件
set autoread 

"激活鼠标的使用
set mouse=a 


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 字体和颜色
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"开启语法
syntax enable 

"设置字体
"set guifont=dejaVu\ Sans\ MONO\ 10 
"
""设置配色
"colorscheme desert 

"高亮显示当前行
set cursorline
hi cursorline guibg=#00ff00
hi CursorColumn guibg=#00ff00


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 折叠 by old1boy  21:52 2010-5-14
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"开启折叠
set nofen
set fdl=0 

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 文字处理 by old1boy 21:53 2010-5-14
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"使用空格来替换tab
set expandtab
"设置所有的tab和缩进为4个空格
set tabstop=4
set shiftwidth=4
set softtabstop=4
set smarttab

"""""""""""""""""""""""""""""""""""""""""""""""""
"=>缩进 by old2boy
"""""""""""""""""""""""""""""""""""""""""""""""""
"缩进,自动缩进(继承前一行的缩进)
"set autoindent命令关闭自动缩进,是下面配置的缩写。
"可使用autoindent命令的简写,即 :set ai 和 :set noai。
"还可以使用 :set ai sw=4在一个命令中打开缩进并设置缩进级别。 
set ai  

"智能缩进
set si 

"自动换行
set wrap 

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Vim 界面 by old3boy
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"Turn on WiLd menu
set wildmenu 

"显示标尺
set ruler 

"设置命令行的高度
set cmdheight=1 

"显示行数
set nu 

"Do not redraw, when running macros.. lazyredraw
set lz 

"设置退格
set backspace=eol,start,indent 

"Bbackspace and cursor keys wrap to
set whichwrap+=<,>,h,l 

"Set magic on
set magic 

"关闭遇到错误时的声音提示
set noerrorbells
set novisualbell 

"显示匹配的括号([{和}])
set showmatch 
"How many tenths of a second to blink
set mat=2 

"高亮显示搜索的内容
set hlsearch

"搜索时不区分大小写
"还可以使用简写(:set ic 和 :set noic)
set ignorecase

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 编码设置 by oldboy 2010
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"设置编码
set encoding=gb18030
"设置文件编码
set fileencodings=gb18030 

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => 其他设置 by oldboy 2010
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
set smartindent
set cin
set showmatch
set guioptions-=T
set vb t_vb=
filetype on
set pastetoggle=<F9>
set background=dark
highlight Search ctermbg=black  ctermfg=white guifg=white guibg=black

bashrc

 

 

 

Unix shell范例精解(第4版)-老男孩推荐shell书

shell-abs-3.9.1_cn

 

 

 

 

shell面试题

1.手机充值

手机充值10元,每发一次短信(输出当前余额)花费1角5分钱,当余额低于1角5分钱不能发短信,提示余额不足,请充值(可以允许用户充值继续发短信),请用while语句实现。
解答:单位换算。统一单位,统一成整数
10元=1000分,1角5分=15分

 

二麻子同学的方法

[root@MySQL scripts]# cat mobile_msg1.sh

#!/bin/sh

TOTAL=1000

MSG_FEE=500

 

function IS_NUM(){

expr $1 + 1 &>/dev/null

if [ $? -ne 0 -a "$1" != "-1" ];then

return 1

fi

return 0

}

 

function consum(){

read -p "Pls input your msg:" TXT

read -p "Are you to send?[y|n]" OPTION

case $OPTION in

[yY]|[yY][eE][sS])

echo "Send successfully!"

((TOTAL=TOTAL-MSG_FEE))

echo "Your have $TOTAL left!"

;;

[nN]|[nN][oO])

echo "Canceled"

;;

*)

esac

}

 

 

function charge(){

if [ $TOTAL -lt $MSG_FEE ];then

read -p "Money is not enough,Are U want to charge?[y|n]" OPT2

case $OPT2 in

y|Y)

while true

do

IS_NUM $CHARGE&&break||{

echo "INVALID INPUT"

exit 100

}

done

((TOTAL+=CHARGE)) && echo "you have $TOTAL money."

;;

n|N)

exit 101

;;

*)

echo "INVALID INPUT!"

exit 102

;;

esac

fi

}

 

main(){

while [ $TOTAL -ge $MSG_FEE ]

do

consum

charge

done

}

main

 

 

#!/bin/sh                                    
sum=1000
i=15
while ((sum>=i))
do
   clear
   ((sum=sum-i))
   echo -ne "\bsend message, $sum\b"
   sleep 0.2
done
clear
echo -e "\033[31;1;5mmoney is not enough:$sum\033[0m"
sleep 10
exit

李想

#!/bin/bash
i=1000
until [ $i -lt 15 ]
do
        ((i=i-15))
        echo "the message:$i"
        if [ $i -lt 15 ];then
                echo "your money is left $i,余额不足"
                read -p "pls Recharge money:" num
                i=$(($num+$i))
        fi
done

刘铮

#!/bin/sh
huafei=1000
i=0
SENDMESSGE(){
   while [ $huafei -gt 960 ]
   do
     huafei=$[$huafei-15]
     let i++
     sleep 1
     echo "当前余额:$huafei,您累计发送短信 $i 条"
done
echo "余额不足,请充值!"
read -p "请输入您要充值的金额:" chongzhi
huafei=$[$huafei+$chongzhi]
echo "您已成功充值,余额为:$huafei."
SENDMESSGE
}
SENDMESSGE

 

 

 

2.猜数字

首先让系统随机生成一个数字,给这个数字定一个范围(数字前50及后50),让用户输入猜的数字,对输入判断,如果不符合数字就给予高与低的提示,根据提示,看你多少次可以猜对?

 


[root@liwx scripts]# vim caishuzi.sh

 

#!/bin/bash

NUM=$(date +%S)

echo "当前苹果价格是每斤$NUM元"

echo "========================"

sleep 1

clear

 

ipple(){

echo ‘这苹果多少钱一斤啊?

请猜0-60的数字‘

read -p "请输入你的价格:" A

expr $A + 1 &>/dev/null

if [ $? -ne 0 ]

then

echo "别逗我了,快猜数字"

ipple

fi

}

 

 

guess(){

if [ $A -eq $NUM ]

then

echo "猜对了,就是$NUM元"

exit 0

elif [ $A -gt $NUM ]

then

echo "嘿嘿,要不你用这个价买?"

ipple

elif [ $A -lt $NUM ]

then

echo "太低太低"

ipple

fi

}

 

main(){

ipple

while true

do

guess

done

}

main

 

 

3.分析apache日志
问题1:计算apache一天的日志access_2010-12-8.log中所有行的日志各元素的访问字节数的总和。给出实现程序。练习日志:见目录下access_2010-12-8.log,也可以用自己的apache日志。请用while循环实现。(3分钟)

拓展:while按行读文件的方式:
方式1:
exec <FILE
sum=0
while read line
do
    cmd
done
方式2:
cat ${FILE_PATH} | while read line
do
    cmd
done
方式3:
while read line
do
    cmd
done<FILE

 

 

[root@MySQL scripts]# cat sum-while.sh 
sum=0
while read line
do
  value=`echo $line|awk ‘{print $10}‘`
   expr $value + 1 &>/dev/null
   [ $? -ne 0 ] && continue
   ((sum+=value))
done<access_2010-12-8.log 
echo $sum

 

 

4.解决DOS攻击

企业实战题6:请用至少两种方法实现!
写一个脚本解决DOS攻击生产案例
提示:根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100,即调用防火墙命令封掉对应的IP,监控频率每隔3分钟。防火墙命令为:iptables -A INPUT -s 10.0.1.10 -j DROP。

方法1

[root@liwx dos]# vim check_dos.sh

 

#!/bin/sh

 

awk ‘{print $1}‘ /service/scripts/dos/access_2010-12-8.log |sort -t "." -k 4|uniq -c >/tmp/dos_ip.log

 

exec </tmp/dos_ip.log

while read line

do

NUM=`echo $line|awk ‘{print $1}‘`

IP=`echo $line|awk ‘{print $2}‘`

IPTAB=`iptables -L -n|grep "$IP"|wc -l`

if [ "$NUM" -gt "3" ]&&[ "$IPTAB" -lt "1" ]

then

iptables -I INPUT -s $IP -j DROP

echo "$IP is dropped" >>/opt/iptab_doop_ip.log

fi

done

 

方法2

[root@mysql 19_shell]# cat check1.sh

#!/bin/sh

while true

do

netstat -an|grep EST|awk -F "[ :]+" ‘{print $6}‘|sort |uniq -c>/opt/c.log

exec</opt/c.log

while read line

do

pv=`echo $line|awk ‘{print $1}‘`

ip=`echo $line|awk ‘{print $2}‘`

if [ $pv -gt 3 ]&&[ `iptables -L -n|grep $ip |wc -l -eq 0` ]

then

iptables -A INPUT -s $ip -j DROP

echo "$ip has jopped">>/tmp/droplist.log

fi

done

sleep 180

done

 

 

 

iptables主要参数

-A 向规则链中添加一条规则,默认被添加到末尾

-T指定要操作的表,默认是filter

-D从规则链中删除规则,可以指定序号或者匹配的规则来删除

-R进行规则替换

-I插入一条规则,默认被插入到首部

-F清空所选的链,重启后恢复

-N新建用户自定义的规则链

-X删除用户自定义的规则链

-p用来指定协议可以是tcp,udp,icmp等也可以是数字的协议号,

-s指定源地址

-d指定目的地址

-i进入接口

-o流出接口

-j采取的动作,accept,drop,snat,dnat,masquerade

--sport源端口

--dport目的端口,端口必须和协议一起来配合使用

 

 

 

 

5.监控mysql主从

企业面试题1:(生产实战案例):监控MySQL主从同步是否异常,如果异常,则发送短信或者邮件给管理员。提示:如果没主从同步环境,可以用下面文本放到文件里读取来模拟:
阶段1:开发一个守护进程脚本每30秒实现检测一次。
阶段2:如果同步出现如下错误号(1158,1159,1008,1007,1062),则跳过错误。
阶段3:请使用数组技术实现上述脚本(获取主从判断及错误号部分)

 

[root@MySQL-master-02 ~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock -e "show slave status\G;"

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 172.16.1.51

                  Master_User: rep

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000006

          Read_Master_Log_Pos: 107

               Relay_Log_File: relay-bin.000013

                Relay_Log_Pos: 253

        Relay_Master_Log_File: mysql-bin.000006

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

              Replicate_Do_DB: 

          Replicate_Ignore_DB: mysql

           Replicate_Do_Table: 

       Replicate_Ignore_Table: 

      Replicate_Wild_Do_Table: 

  Replicate_Wild_Ignore_Table: 

                   Last_Errno: 0

                   Last_Error: 

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 107

              Relay_Log_Space: 549

              Until_Condition: None

               Until_Log_File: 

                Until_Log_Pos: 0

           Master_SSL_Allowed: No

           Master_SSL_CA_File: 

           Master_SSL_CA_Path: 

              Master_SSL_Cert: 

            Master_SSL_Cipher: 

               Master_SSL_Key: 

        Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error: 

               Last_SQL_Errno: 0

               Last_SQL_Error: 

  Replicate_Ignore_Server_Ids: 

             Master_Server_Id: 1

解答:

#!/bin/sh

 

while true

do

error=(1158 1159 1008 1007 1062 1236)

#CMD="mysql -uroot -poldboy123 -S /data/3307/mysql.sock"

CMD=`cat /service/scripts/mysql/mysql.log |egrep "Running|Behind_Master|Last_SQL_Errno"|awk ‘{print $2}‘`

#array2=($($CMD -e "show slave status\G"|egrep "Running|Behind_Master|Last_SQL_Errno"|awk ‘{print $NF}‘))

array2=($CMD)

if [ "${array2[0]}" == "Yes" -a "${array2[1]}" == "Yes" -a "${array2[2]}" == "0" ];then

echo "mysql slave is OK"

else

for i in ${error[*]}

do

if [ "${array2[3]}" == "$i" ];then

#$CMD -e "stop slave;set global sql_slave_skip_counter=1;start slave;"

sed -i ‘s#SQL_Errno:.*$#SQL_Errno: 0#g‘ /service/scripts/mysql/mysql.log

echo $i

fi

done

echo "slave is not OK"

echo "slave is not OK"|mail -s "error about slave info $(date +%F_%R)" 79441650@qq.com

fi

sleep 50

done

王二麻的方法

 

#!/bin/bash
###########################################
# File Name: mon_mysql.sh
# Author: Troy
# mail: troy@trnux.com
# Created Time: 2015年08月17日 星期一 09时35分07秒
#########################################
#Define vars
REPORT_FILE=/app/logs/mon_mysql/error.log
MYSQL_HOST="192.168.16.102"
MASTER_PORT=3306
SLAVE_PORT=3307
MYSQL_USER="monitor"
MYSQL_PWD="123456"
ERR_CODE_ARR=(1158 1159 1008 1007 1062)
MYSQL_CMD="mysql -h $MYSQL_HOST -P $SLAVE_PORT -u $MYSQL_USER -p$MYSQL_PWD"
[ ! -d `dirname $REPORT_FILE` ]&&mkdir `dirname $REPORT_FILE` -p
function report(){
#accept STRING as $1
echo "`date +%F_%T`:$1"|tee -a $REPORT_FILE
}
function rec_mysql(){
#accept error code as $1
#1158,1159,1008,1007,1062
ERR_CODE=$1
echo ${ERR_CODE_ARR[@]}|grep -w "$ERR_CODE" &>/dev/null
if [ $? -eq 0 ];then
SQL_QUERY="stop slave;set global sql_slave_skip_counter = 1;start slave;"
$MYSQL_CMD -e "$SQL_QUERY"
report "Err $ERR_CODE has been solved!"
return 0
else
report "Please Handle Error $ERR_CODE Mannuallly!"
return 1
fi
}
function check_rep(){
#generate mysql info arr
MYSQL_INFO_ARR=(`$MYSQL_CMD -e "show slave status\G"|grep -iE "running|behind|last_errno"|sed -r ‘s#\s+##g‘`)
#echo arr for debugging
echo ${MYSQL_INFO_ARR[@]}
#handle err code
if [ ${MYSQL_INFO_ARR[0]#*:} != "Yes" -o ${MYSQL_INFO_ARR[1]#*:} != "Yes" ]
then
report "MySQL_REPLICATION doen‘t work!"
rec_mysql ${MYSQL_INFO_ARR[2]#*:}
return 1
elif [ ${MYSQL_INFO_ARR[3]#*:} -ne 0 ]
then
report "Take Care,Slave is lagged!"
else
echo "MySQL Replication is Healthy!"
break 
fi
return 0
}
function check_srv(){
echo "\n"|telnet $MYSQL_HOST $MASTER_PORT 2>/dev/null|grep -i "connected" &>/dev/null
if [ $? -ne 0 ];then
report "MySQL Master Doesn‘t Work!Check it"
return 1
fi
echo "\n"|telnet $MYSQL_HOST $SLAVE_PORT 2>/dev/null|grep -i "connected" &>/dev/null
if [ $? -ne 0 ];then
report "MySQL Slave Doesn‘t Work!Check it"
return 1
fi
return 0
}
function main(){
while true
do
check_srv
while [ $? -eq 0 ]
do
check_rep
done
sleep 5
done
}
main

 

 

6.批量创建随机数文件

企业面试题2:使用for循环在/oldboy目录下通过随机小写10个字母加固定字符串oldboy批量创建10个html文件,名称例如为:

[root@oldboy oldboy]# sh /server/scripts/oldboy.sh
[root@oldboy oldboy]# ls
coaolvajcq_oldboy.html  qnvuxvicni_oldboy.html  vioesjmcbu_oldboy.html
gmkhrancxh_oldboy.html  tmdjormaxr_oldboy.html  wzewnojiwe_oldboy.html
jdxexendbe_oldboy.html  ugaywanjlm_oldboy.html  xzzruhdzda_oldboy.html
qcawgsrtkp_oldboy.html  vfrphtqjpc_oldboy.html

解答:

  1. 先判断oldboy目录是否存在,不存在则创建

#!/bin/sh

 

[ ! -d /oldboy ]&& mkdir /oldboy

cd /oldboy

 

2.随机小写10个字母

[root@mysql ~]# tr -dc "a-z"</dev/urandom|head -c 10

vfmiiqlobi

head -c <字节> 显示字节数

随机字符生成单词

tr 替换字符串 -c str1的补集 d 删除str1的字符 dc表示删除str1的补集字符,即保留str1字符

/dev/random存储系统当前运行的环境的实时数据,可以看作系统某时候的唯一值数据,提供优质随机数。实测出不了结果

/dev/urandom是非阻塞的随机数产生器,读取时不会产生阻塞,速度更快、安全性较差的随机数发生器。

扩展:

可通过读取Linux的uuid码

UUID码全称是通过唯一识别码,UUID格式是:包含32个16进制数字,以"_"连接号分为五段,形式为8-4-4-4-12的32个字符。Linux的uuid码也是由内核提供的,在/proc/sys/kernel/random/uuid这个文件内。cat /proc/sys/kernel/random/uuid每次获取到的数据都会不同。

数字加字母的随机数

[root@mysql ~]# cat /proc/sys/kernel/random/uuid| md5sum | cut -c 1-10

f4365be7c3

 

1)生成随机数(0-32767)

[root@liwx ~]# echo $RANDOM

14436

[root@liwx ~]# echo $RANDOM

24119

[root@liwx ~]# echo $RANDOM

31196

2)取8位数字随机数

[root@liwx ~]# echo $((RANDOM**3))

3220809592832

[root@liwx ~]# echo $((RANDOM**3))|cut -c 1-8

94380757

3)取8位随机md5值
[root@oldboy scripts]# echo $RANDOM|md5sum|cut -c 2-9
ef8e0175

 

 

解答脚本

#!/bin/sh

 

[ ! -d /oldboy ]&& mkdir /oldboy

cd /oldboy

for i in `seq 10`

do

#RAN=`tr -dc "a-z"</dev/urandom|head -c 10`

RAN=`echo $RANDOM|md5sum|cut -c 2-11|tr [0-9] [a-j]`

touch "$RAN"_liwx.html

#touch ${$RAN}_liwx.html

done

7.批量改名

企业面试题3:请用至少两种方法实现!
将以上文件名中的
oldboy全部改成oldgirl(用for循环实现),并且html改成大写。

[root@liwx oldboy]# echo sed.sh

sed.sh

[root@liwx oldboy]# echo sed.sh |sed ‘s#sed#abc#g‘

abc.sh

 

[root@liwx oldboy]# mv sed.sh `echo sed.sh |sed ‘s#sed#abc#g‘`

[root@liwx oldboy]# ls

abc.sh

法1

#!/bin/sh

[ ! -d /oldboy ]&& exit

 

cd /oldboy

for i in `ls *.html`

do

mv $i `echo $i|sed ‘s#liwx.html#old.HTML#g‘`

done

 

法2

rename old.HTML liwx.html *.HTML

 

8.批量创建账号,并设置密码

企业面试题4:
批量创建10个系统帐号oldboy01-oldboy10并设置密码(密码为随机8位字符串)。

[root@liwx user]# vim mkuser.sh

 

#!/bin/sh

 

for i in `seq -w 10`

do

pass=`echo $RANDOM|md5sum|cut -c 1-8`

useradd liwx$i &&

echo $pass|passwd --stdin liwx$i

echo -e "liwx$i\t $pass" >>/tmp/pass.txt

done

 

[root@liwx tmp]# cat /tmp/pass.txt

liwx01 5d400854

liwx02 81ef73c2

liwx03 62688d37

liwx04 6eea713a

liwx05 dac54109

liwx06 50299937

liwx07 fbfb118a

liwx08 76ec371b

liwx09 a92d9ac1

liwx10 e4fe29ea

 

扩展

seq -w 指定输出数字同宽,前面不足的用0补全,即与位数最多的数对齐

echo -e 处理特殊字符

若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:

\a 发出警告声;

\b 删除前一个字符;

\c 最后不加上换行符号;

\f 换行但光标仍旧停留在原来的位置;

\n 换行且光标移至行首;

\r 光标移至行首,但不换行;

\t 插入tab;

\v 与\f相同;

\\ 插入\字符;

\nnn 插入nnn(八进制)所代表的ASCII字符;

 

 

seq -w 指定输出数字同宽,前面不足的用0补全,即与位数最多的数对齐

echo -e 处理特殊字符

若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:

\a 发出警告声;

\b 删除前一个字符;

\c 最后不加上换行符号;

\f 换行但光标仍旧停留在原来的位置;

\n 换行且光标移至行首;

\r 光标移至行首,但不换行;

\t 插入tab;

\v 与\f相同;

\\ 插入\字符;

\nnn 插入nnn(八进制)所代表的ASCII字符;

9.判断在线IP

企业面试题5:
写一个脚本,实现判断10.0.0.0/24网络里,当前在线用户的IP有哪些(方法有很多)

 

#!/bin/sh

 

. /etc/init.d/functions

for n in {140..160}

do

{

ping -c 1 -W 1 192.168.203.$n &>/dev/null

if [ "$?" -eq "0" ];then

echo -e "\033[32m192.168.203.$n is ONLINE\033[0m `action "" /bin/true`"

echo "192.168.203.$n" >>/tmp/online.txt

else

echo -e "\033[31m192.168.203.$n is OFFLINE\033[0m `action "" /bin/false`"

echo "192.168.203.$n" >>/tmp/unline.txt

fi

}&

done

wait

 

 

技术分享

10.mysql多实例启动脚本

企业实战题7:
开发mysql多实例启动脚本:
已知mysql多实例启动命令为:mysqld_safe --defaults-file=/data/3306/my.cnf &
停止命令为:mysqladmin -u root -poldboy123 -S /data/3306/mysql.sock shutdown
请完成mysql多实例启动启动脚本的编写
要求:用函数,case语句、if语句等实现。

我的方法

#!/bin/sh

# chkconfig: 2345 20 80

# description: start mysql and stop mysql scripts.

 

. /etc/init.d/functions

 

port="3306"

path="/application/mysql/bin"

user="root"

pass="liwx123"

sock="/data/$port/mysql.sock"

cnf="/data/$port/my.cnf"

 

USAGE(){

echo "PLEASE USAGE: $0 {start|stop|restart|status}"

}

 

start(){

if [ `ss -lntup|grep "$port"|wc -l` -ne "1" ];then

#print "starting MySQL.........\n"

$path/mysqld_safe --defaults-file=$cnf &>/dev/null &

action "Starting $port/mysql......." /bin/true

else

echo "$port/mysql is running........."

fi

}

 

stop(){

if [ `ss -lntup|grep "$port"|wc -l` -ne "1" ];then

echo "$port/mysql is stopped........."

else

$path/mysqladmin -u$user -p$pass -S $sock shutdown &>/dev/null

action "Stoping $port/mysql......." /bin/true

fi

}

 

restart(){

stop

sleep 2

start

}

 

status(){

if [ `ss -lntup|grep "$port"|wc -l` -ne "1" ];then

echo "$port/mysql is stopping"

else

echo "$port/mysql is running"

fi

}

 

case "$1" in

start)

start

;;

stop)

stop

;;

restart)

restart

;;

status)

status

;;

*)

USAGE

esac

 

 

谢迪的方法

#!/bin/sh

# chkconfig: 2345 20 80

# description: start mysql and stop mysql scripts.

. /etc/init.d/functions

path=/application/mysql/bin/

user="root"

pass="oldboy123"

sock="/data/3306/mysql.sock"

pos="/data/3306/my.cnf"

USAGE(){

echo "USAGE: $0 {start|stop|restart}"

}

start_mysql(){

$path/mysqld_safe --defaults-file=$pos &>/dev/null &

if [ $? -eq 0 ];then

action "mysql start" /bin/true

else

action "mysql start" /bin/false

fi

}

stop_mysql(){

$path/mysqladmin -u$user -p$pass -S $sock shutdown &>/dev/null

if [ $? -eq 0 ];then

action "mysql stop" /bin/true

else

action "mysql stop" /bin/false

fi

}

restart_mysql(){

stop_mysql

sleep 3

start_mysql

}

case "$1" in

start)

start_mysql

RETVAL=$?

;;

stop)

stop_mysql

RETVAL=$?

;;

restart)

stop_mysql

start_mysql

RETVAL=$?

;;

*)

USAGE

exit 1

esac

exit $RETVAL:

加入开机启动项

[root@mysql shell_job]# cp mysql /etc/init.d/mysql

[root@mysql shell_job]# chmod +x /etc/init.d/mysql

[root@mysql shell_job]# chkconfig --add mysql

[root@mysql shell_job]# chkconfig mysql on

[root@mysql shell_job]# chkconfig --list mysql

mysql 0:off 1:off 2:on 3:on 4:on 5:on 6:off

[root@mysql shell_job]# chkconfig mysql off

[root@mysql shell_job]# chkconfig --list mysql

mysql 0:off 1:off 2:off 3:off 4:off 5:off 6:off

 

 

 

 

 

法2

#!/bin/bash

port=3306

mysql_user="root"

mysql_pwd="lixiang123"

Cmdpath=/usr/local/mysql/bin

mysql_sock="/tmp/mysql.sock"

#start function

function_start_mysql()

{

if [ `netstat -lntup|grep "$port"|wc -l` -ne 1 ];then

printf "Starting Mysql.....\n"

/bin/sh ${Cmdpath}/mysql_safe --defaults-file=/etc/my.cnf >/dev/null 2>&1

else

printf "mysql is running....."

fi

}

#stop function

function_stop_mysql()

{

if [ `netstat -lntup|grep "$port"|wc -l` -ne 1 ];then

printf "mysql is stopped...\n"

exit

else

printf "stoping mysql....\n"

${Cmdpath}/mysqladmin -u${mysql_user} -p${mysql_pwd} -S /tmp/mysql.sock shudown

fi

}

#restart function

function_restart_mysql()

{

printf "reasting mysql....\n"

function_stop_mysql

sleep 2

function_start_mysql

}

case "$1" in

start)

function_start_mysql

;;

stop)

function_stop_mysql

;;

restart)

function_restart_mysql

;;

*)

printf "Usage:/tmp/mysql.sock/mysql {start|stop|restart}\n"

esac

 

 

法3

#!/bin/sh

#chkconfig: 2345 56 24

#description: This is about rysnc restart shell

. /etc/init.d/functions

RETVAL=0

prog=mysql

lockfile=/var/lock/subsys/mysql

#[ $UID -eq 0 ] && [ -e /data/3306/my.cnf ] && . /data/3306/my.cnf

start(){

if [ $UID -ne 0 ];then

echo "User has insuffcient privilege."

exit 4

fi

if [ ! -f /data/3306/mysql.pid ];then

/application/mysql/bin/mysqld_safe --defaults-file=/data/3306/my.cnf &>/dev/null &

RETVAL=$?

[ $RETVAL -eq 0 ] && touch $lockfile &&

action "Starting $prog......" /bin/true

fi

}

stop(){

#kill `cat /application/nginx/logs/nginx.pid`

/application/mysql/bin/mysqladmin -u root -poldboy123 -S /data/3306/mysql.sock shutdown &>/dev/null

RETVAL=$?

[ $RETVAL -eq 0 ] && rm -f $lockfile

action "Stopping $prog......" /bin/true

}

restart(){

start

stop

}

status(){

if [ -e $lockfile ];then

echo $prog is running

else

echo "${prog} is not running"

fi

}

 

case "$1" in

start)

start

;;

stop)

stop

;;

status)

status

;;

restart)

restart

;;

*)

echo "USAGE:$0 {start|stop|restart}"

esac

 

 

11.mysql分库分表备份

 

企业实战题8:如何实现对MySQL数据库进行分库备份,请用脚本实现

分库备份的脚本

[root@MySQL scripts]# cat bak_by_db.sh

#!/bin/sh

MYUSER=root

MYPASS=oldboy123

SOCKET=/data/3306/mysql.sock

MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"

MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"

BAKPATH="/server/backup/$(date +%F)"

[ ! -d $BAKPATH ] && mkdir -p $BAKPATH

 

for dbname in `$MYCMD -e ‘show databases;‘|sed ‘1d‘|grep -v "_schema"`

do

$MYDUMP -B -x --events $dbname|gzip >$BAKPATH/${dbname}.sql.gz

if [ $? -eq 0 ];then

echo "$dbname" >>$BAKPATH/${dbname}.log

fi

done

 

 

 

分库分表备份

#!/bin/sh

MYUSER=root

MYPASS=liwx123

SOCKET=/data/3306/mysql.sock

MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"

MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"

BAKPATH="/server/backup/$(date +%F)"

[ ! -d $BAKPATH ] && mkdir -p $BAKPATH

 

for dbname in `$MYCMD -e ‘show databases;‘|sed ‘1d‘|grep -v "_schema"`

do

for tabname in `$MYCMD -e "use $dbname;show tables;"|sed ‘1d‘`

do

$MYDUMP -x --events ${dbname} ${tabname}|gzip >$BAKPATH/${dbname}_${tabname}.sql.gz

if [ $? -eq 0 ];then

echo "${dbname}_${tabname}" >>$BAKPATH/${dbname}.${tabname}.log

fi

done

done

 

 

 

 

李想的方法

分库

#!/bin/sh

myuser=root

mypasswd=liwx123

socket=/tmp/mysql.sock

mycmd="mysql -u$myuser -p$mypasswd -S $socket"

mydump="mysqldump -u$myuser -p$mypasswd -S $socket"

for database in `$mycmd -e "show databases;"|sed ‘1,2d‘|egrep -v "mysql|performance_schema"`

do

$mydump $database|gzip >/data/backup/${database}_$(date +%F)_sql.gz

done

 

分库分表

#!/bin/sh

myuser=root

mypasswd=lixiang123

socket=/tmp/mysql.sock

mycmd="mysql -u$myuser -p$mypasswd -S $socket"

mydump="mysqldump -u$myuser -p$mypasswd -S $socket"

for database in `$mycmd -e "show databases;"|sed ‘1,2d‘|egrep -v "mysql|performance_schema"`

do

for tables in `mydump -e "show tables from $databses;"|sed ‘1d‘`

do

$mydump $database $tables|gzip >/data/backup/${database}/${databse}_${tables}_$(date +%F)_sql.gz

done

done

 

12.打印字母数不大于6的单词

企业面试题10:请用至少两种方法实现!
bash for循环打印下面这句话中字母数不大于6的单词(昆仑万维面试题)。
I am oldboy teacher welcome to oldboy training class.

求字符串长度常用的三种方法:

expr length "$OLDBOY"

echo $OLDBOY|wc -L

echo ${#OLDBOY}

 

 

我的方法

[root@gw for]# vim bi_daxiao.sh

 

#!/bin/sh

 

for i in I am oldboy teacher welcome to oldboy training class

do

#if [ `echo $i|wc -L` -lt 6 ];then

if [ "${#i}" -lt "6" ];then

echo $i

fi

done

echo ==========================================================

arr=(I am oldboy teacher welcome to oldboy training class)

for i in ${arr[*]}

do

if [ ${#i} -lt 6 ];then

echo $i

fi

done

 

 

方法一:

#!/bin/bash

for i in I am oldboy teacher welcome to oldboy training class

do

if [ `echo $i|wc -L` -lt 6 ]

then

echo $i

fi

done

 

方法二:

echo "I am oldboy teacher welcome to oldboy training class"|awk ‘{for(i=1;i<=NF;i++) if(length($i)<6 ) print $i}‘

 

方法三:

array=(I am oldboy teacher welcome to oldboy training class)

for i in ${array[*]}

do

if [ `expr length $i` -lt 6 ];then

echo $i

fi

done

 

方法四:

 

#!/bin/bash

arr=(I am oldboy teacher welcome to oldboy training class)

for((i=0;i<${#arr[*]};i++))

do

if [ ${#arr[i]} -le 6 ]

then

echo ${arr[i]}

fi

done

 

 

13.比较2个整数大小

企业面试题11:开发shell脚本分别实现以脚本传参以及read读入的方式比较2个整数大小。以屏幕输出的方式提醒用户比较结果。注意:一共是开发2个脚本。当用脚本传参以及read读入的方式需要对变量是否为数字、并且传参个数做判断。

我的方法read

[root@gw for]# vim bi_daxiao.sh

 

#!/bin/sh

 

read -p "Please input two number:" a b

expr $a + $b + 1 &>/dev/null

RETVAL=$?

[ $RETVAL -ne 0 ]&& echo "ple input two number"||

if [ "$a" -lt "$b" ];then

echo "$a < $b"

elif [ "$a" -gt "$b" ];then

echo "$a > $b"

elif [ "$a" -eq "$b" ];then

echo "$a = $b"

else

echo "ple input two number"

fi

 

传参方式

[root@gw for]# vim bi_dx_02.sh

 

#!/bin/sh

 

a=$1

b=$2

 

#no.1

if [ $# -ne 2 ];then

echo "USAGE: sh $0 numb1 numb2"

exit

fi

 

expr $a + $b + 1 &>/dev/null

RETVAL=$?

if [ $RETVAL -ne 0 ];then

echo "ple input two number"

exit

fi

 

#no.2

if [ $a -gt $b ];then

echo "$a > $b"

elif [ $a -lt $b ];then

echo "$a < $b"

else

echo "$a = $b"

fi

 

 

 

 

#!/bin/bash

first=$1

second=$2

echo $first

echo $second

if [ $1 -eq $2 ]

then

echo "the result is equal"

fi

if [ $1 -lt $2 ]

then

echo "$1小于$2"

else

echo "$1大于$2"

fi

 

 

14.菜单,一键安装web服务

企业面试题12:打印选择菜单,一键安装Web服务:

[root@oldboyscripts]# sh menu.sh

   1.[install lamp]

   2.[install lnmp]

   3.[exit]

   pls input the num you want:

要求:

1、当用户输入1时,输出"startinstalling lamp."然后执行/server/scripts/lamp.sh,脚本内容输出"lamp is installed"后退出脚本;

2、当用户输入2时,输出"startinstalling lnmp."然后执行/server/scripts/lnmp.sh输出"lnmp is installed"后退出脚本;

3、当输入3时,退出当前菜单及脚本;

4、当输入任何其它字符,给出提示"Input error"后退出脚本。

5、要对执行的脚本进行相关条件判断,例如:脚本是否存在,是否可执行等。

我的方法

 

#!/bin/sh

 

menu(){

cat <<EOF

----------------------------------------

|****Please Enter Your Choice:[0-3]****|

----------------------------------------

1.[install lamp]

2.[install lnmp]

3.[exit]

EOF

}

 

lamp(){

echo "startinstalling lamp.."

[ -f /service/scripts/lamp.sh ]&&

/bin/sh /service/scripts/lamp.sh||

echo "instlling lamp.sh error"

}

 

lnmp(){

echo "startinstalling lnmp.."

[ -f /service/scripts/lnmp.sh ]&&

/bin/sh /service/scripts/lnmp.sh||

echo "instlling lnmp.sh error"

}

 

exit1(){

echo "byebye!!"

exit

}

 

menu1(){

read -p "please input a number:" a

case "$a" in

1)

lamp

sleep 2

clear

;;

2)

lnmp

sleep 2

clear

;;

3|exit)

clear

exit1

;;

*)

echo "input error,please input [1-3]"

sleep 1

menu

esac

}

 

while true

do

clear

menu

menu1

done

 

 

 

简单的方法

[root@mysql scripts]# cat caidan.sh

#!/bin/sh

#no1

cat <<EOF

1.[install lamp]

2.[install lnmp]

3.[exit]

EOF

 

#no2

read -p "pls input the num you want:" a

 

if [ $a != 1 ] &&[ $a != 2 ]&&[ $a != 3 ]

then

echo "Input error"

exit 1

fi

 

#no3

if [ $a -eq 1 ]

then

echo "startinstalling lamp."

[ -f /server/scripts/lamp.sh ]&&[ -x /server/scripts/lamp.sh ]&&

/bin/sh /server/scripts/lamp.sh

exit

fi

 

if [ $a -eq 2 ]

then

echo "startinstalling lnmp."

[ -f /server/scripts/lnmp.sh ]&&[ -x /server/scripts/lnmp.sh ]&&

/bin/sh /server/scripts/lnmp.sh &>/dev/null

exit

fi

 

if [ $a -eq 3 ]

then

echo "byebye!!"

exit

fi

 

 

李想的方法

#!/bin/bash

echo -e "\033[32m========================================\033[0m"

echo -e "\033[32m The Author : lx \033[0m"

echo -e "\033[32m Description:lamp/lnmp \033[0m"

echo -e "\033[32m QQ:695915099 \033[0m"

echo -e "\033[32m========================================\033[0m"

menu(){

cat << EOF

----------------------------------------

|****Please Enter Your Choice:[0-3]****|

----------------------------------------

1.[install lamp]

2.[install lnmp]

3.[exit]

EOF

}

menu1(){

cat << EOF

----------------------------------------

|****Please Enter Your Choice:[0-4]****|

----------------------------------------

1.[install apache]

2.[install php]

3.[install mysql]

4.[back]

EOF

}

menu2(){

cat << EOF

----------------------------------------

|****Please Enter Your Choice:[0-4]****|

----------------------------------------

1.[install nginx]

2.[install php]

3.[install mysql]

4.[back]

EOF

}

lamp(){

clear

while true

do

menu1

read -p "please input a number:" num1

case "$num1" in

1)

echo -e "\033[32mThe Apache is installing......\033[0m"

sleep 3

;;

2)

echo -e "\033[32mThe Php is installing......\033[0m"

sleep 3

;;

3)

echo -e "\033[32mThe Mysql is installing......\033[0m"

sleep 3

;;

4)

clear

break

;;

*)

esac

done

}

lnmp(){

clear

while true

do

menu2

read -p "please input a number:" num2

case "$num2" in

1)

echo -e "\033[32mThe Nginx is installing......\033[0m"

sleep 3

;;

2)

echo -e "\033[32mThe Php is installing......\033[0m"

sleep 3

;;

3)

echo -e "\033[32mThe Mysql is installing......\033[0m"

sleep 3

;;

4)

clear

break

;;

*)

esac

done

}

declare flag=0

while [ "$flag" -eq 0 ]

do

menu

while true

do

read -p "pls input the you want:" num

expr $num + 1 &>/dev/null

REVGRS=$?

[ $REVGRS -ne 0 ] &&{

echo "pls input a intger number!"

exit 1

}

[ $num -eq 1 ] && {

lamp

}

[ $num -eq 2 ] && {

lnmp

}

[ $num -eq 3 ] && {

exit

}

break

done

##############################################

[ $num -ge 4 ] && {

echo -e "\033[32mplease select 1 or 2 or 3\033[0m"

menu

read -p "pls input the you want:" num3

[ $num3 -eq 1 ] && {

lamp

}

[ $num3 -eq 2 ] && {

lnmp

}

[ $num3 -eq 3 ] && {

exit

}

}

done

 

15.监控web服务

企业面试题13:

1、监控web服务是否正常,不低于3种监控策略。

2、监控db服务是否正常,不低于3种监控策略。
要求间隔1分钟,持续监控。
web:

 

监控网站异常最简单的可以以端口是不是通畅,是不是打开为目标,监控端口有2种方式,第一种,如果在本地监控的话可以用ss netstat lsof第二种,如果在监控服务器上远程监控客户端web服务器可以通过telnet nmap nc这样的方式,端口的监控只是一般的监控,端口通畅了不代表服务是好的,它只是一个必要条件,但是监控端口比较简单,所以在常规情况下这个必要条件我们可能也会用,并且我们还会用其他的端口监控方式,那就是,进程数,通过ps看一下本地的进程数,然后来判断,这种方式的缺点就是只适合在本地监控,另外我们可以通过header这种远程本地都适合的方式看看返回值是否为200,来进行监控,另外最好的监控方式就是模拟用户的方式,就是说用户怎么认为不正常我们就用什么方式来监控,这种方式第一个是wget ,第二个是curl 第三个我们可以用php 程序去写监控,这个是最好的方式。

总的来说:监控有端口,进程,header ,wget ,curl,php最后2个是准确度最高的,企业里面我们常用的就是端口+应用程序,或者是wget 和curl的形式。

1.根据进程数判断

[root@lnmp ~]# cat check_web.sh

#!/bin/sh

while true

do

if [ `ps -ef |grep nginx|egrep -v "php-fpm|grep"` -ge 2 ];then

echo "nginx is running"

else

echo "nginx is stopped"

/application/nginx/sbin/nginx

fi

sleep 60

done

 

2.根据端口判断

[root@lnmp ~]# cat check_web1.sh

#!/bin/sh

while true

do

if [ `lsof -i:80|grep "nginx"|wc -l` -ge 2 ];then

echo "Nginx is running"

else

echo "Nginx is stopped"

/application/nginx/sbin/nginx

fi

sleep 60

done

 

3.使用wget和curl方式

curl示例

[root@gw caidan]# curl -I -s -w "%{http_code}\n" www.baidu.com -o /dev/null

200

 

脚本

[root@lnmp ~]# cat check_web1.sh1

#!/bin/sh

while true

do

if [ "`curl -I -s -w "%{http_code}\n" 10.0.0.225 -o /dev/null`" != "200" ];then

echo "httpd is not running"

else

echo "httpd is running"

fi

sleep 60

done

 

 

wget示例

[root@gw caidan]# wget -T 10 --spider -t 2 www.baidu.com

[root@gw caidan]# echo $?

0

 

脚本

[root@lnmp ~]# cat check_web1.sh2

#!/bin/sh

while true

do

port=`wget -T 10 --spider -t 2 10.0.0.225 &>/dev/null`

if [ $? -ne 0 ];then

echo "httpd is not running"

else

echo "httpd is running"

fi

sleep 60

done

 

方法2

#!/bin/bash

while true

do

wget --spider --timeout=2 --tries=2 $1 &>/dev/null

if [ $? -ne 0 ];then

echo "web is error"

else

echo "web is ok"

fi

sleep 60

done

 

 

4.监控MySQL

[root@lnmp ~]# cat check_db01.sh

#!/bin/sh

while true

do

if [ "`ss -lnt|grep 3306|awk -F "[ |:]+" ‘{print $5}‘`" == "3306" ]

#if [ `lsof -i tcp:3306|wc -l` -gt 0 ]

if [ `ps -ef|grep mysql|grep -v grep|wc -l` -gt 0 ]

if [ ` nmap 10.0.0.7 -p 3306|grep "open"|wc -l` -gt 0 ]

#if [ `nc -w 2 10.0.0.7 3306 &>/dev/null&&echo ok|grep ok|wc -l` -gt 0 ]

 

then

echo "mysql is running"

else

echo "mysql is stopped."

/data/3306/mysql start

fi

sleep 60

done

 

 

 

李想

#!/bin/sh

if [ "`netstat -lnt|grep 3306|awk -F "[ :]+" ‘{print $5}‘`" = "3306" ]

#cuo-if [ `netstat -lnt|grep 3306|awk -F "[ :]+" ‘{print $5}‘` -eq 3306 ]

#if [ `ps -ef|grep mysql|grep -v grep|wc -l` -gt 0 ]

#if [ `nc -w 2 10.0.0.7 3306 &>/dev/null&&echo ok|grep ok|wc -l` -gt 0 ]

#if [ `nmap 10.0.0.7 -p 3306 2>/dev/null|grep open|wc -l` -gt 0 ]

#if [ `netstat -lntup|grep mysqld|wc -l` -gt 0 ]

#if [ `lsof -i tcp:3306|wc -l` -gt 0 ]

then

echo "MySQL is Running."

else

echo "MySQL is Stopped."

/data/3306/mysql start

fi

 

 

16.监控memcache服务

企业面试题14:监控memcache服务是否正常,模拟用户(web客户端)检测。

使用nc命令加上set/get来模拟检测,以及监控响应时间及命中率。

 

水电费第三方

 

 

17.监控文件是否被恶意篡改

企业面试题15:面试及实战考试题:监控web站点目录(/var/html/www)下所有文件是否被恶意篡改(文件内容被改了),如果有就打印改动的文件名(发邮件),定时任务每3分钟执行一次(10分钟时间完成)。

解答:过程

  1. 大小可能会变化
  2. 修改时间会变化
  3. 文件内容会变化,md5指纹
  4. 增加或者删除文件

 

find /data/html/bbs/ -type f|xargs md5sum >/server/scripts/md5/md5.`date +%F_%R`.log

思路:

1.文件被修改 用md5指纹

2.文件数量变化 用diff对比

 

 

 

我的方法

#!/bin/sh

 

path=/data/html/bbs

md5_log=/server/scripts/md5/md5.2015-09-25_01:40.log

old_num=/server/scripts/md5/num.2015-09-25_02:29.log

err01_log=/tmp/md5_err01.log

err02_log=/tmp/md5_err02.log

[ ! -f $err01_log ]&& touch $err01_log

[ ! -f $err02_log ]&& touch $err02_log

 

while true

do

fail_md5=`md5sum -c $md5_log 2>/dev/null|grep FAILED`

check_md5=`md5sum -c $md5_log 2>/dev/null|grep FAILED|wc -l`

find $path -type f >/tmp/new_md5.log

 

if [ "$check_md5 -ne 0" ] || [ `cat $old_num|wc -l` -ne `cat /tmp/new_md5.log|wc -l` ]

then

echo $fail_md5 >$err01_log

diff $old_num /tmp/new_md5.log >$err02_log

#mail -s "cuangai bbs $(date)" 79441650@qq.com

cat $err01_log $err02_log

fi

sleep 5

done

 

 

李想

find /var/html/www -type f -mtime 0|xargs md5sum > lx01.log 【脚本之外首先执行】

!#/bin/bash

while true

do

find /var/html/www -type f -mtime 0|xargs md5sum > lx02.log

diff lx01.log lx02.log |grep "^>"|awk ‘{print $3}‘|xargs echo >>/tmp/check.log

mail -s modifile lx@qq.com </tmp/check.log

sleep 180

done

 

 

谢迪

[root@mysql xiedi]# cat md5sum.sh

#!/bin/sh

#oldboy linux by xiedi

 

pass=/server/scripts/xiedi/

path=/var/html/www

n1=`find $path -type f|wc -l`

n2=`cat $pass/old_file.log |wc -l`

while true

do

f=`md5sum -c /server/scripts/xiedi/md5sum.db 2>/dev/null|grep "FAILED"|wc -l`

if [ $f -ne 0 ] || [ $n1 -ne $n2 ]

then

find $path -type f>$pass/new_file.log

diff $pass/new_file.log $pass/old_file.log>/opt/check.log

echo "`md5sum -c /server/scripts/xiedi/md5sum.db 2>/dev/null|grep "FAILED"`">>/opt/check.log

mail -s "md5sum has change `date`" 397731124@qq.com</opt/check.log

fi

sleep 3

done

 

 

18.rsync系统启动脚本

企业面试题16:企业案例:写网络服务独立进程模式下rsync的系统启动脚本

例如:/etc/init.d/rsyncd {start|stop|restart} 。
要求:
1.要使用系统函数库技巧。
2.要用函数,不能一坨SHI的方式。
3.可被chkconfig管理。

解答:思路

  1. rsync启动命令: rsync --daemon
  2. rsync 停止命令: kill -USR2 /var/run/rsyncd.pid
  3. 加入到chkconfig管理,先把脚本拷贝到/etc/init.d下面,给脚本执行权限,然后通过chkconfig --add rsync添加到管理

     

    我的方法

    [root@gw rsync]# vim rsyncd.sh

     

    #!/bin/sh

    # chkconfig: 2345 20 80

    # description: start rsync and stop rsync scripts.

     

    . /etc/init.d/functions

     

    pidfile=/var/run/rsyncd.pid

     

    start(){

    if [ ! -f $pidfile ];then

    rsync --daemon &>/dev/null

    action "starting rsync...." /bin/true

    else

    echo "rsync is running"

    fi

    }

     

    stop(){

    if [ ! -f $pidfile ];then

    echo "rsync is not running"

    else

    kill -USR2 `cat $pidfile`

    rm -f $pidfile

    action "stopping rsync...." /bin/true

    fi

    }

     

    restart(){

    stop

    sleep 2

    start

    }

     

    case "$1" in

    start)

    start

    ;;

    stop)

    stop

    ;;

    restart)

    restart

    ;;

    *)

    echo "USAGE: $0 {start|stop|restart}"

    esac

     

     

     

    李想

    #!/bin/bash

    #start the rsync

    #chkconfig: 2345 56 24

    #description: This is about rysnc restart shell

     

    . /etc/init.d/functions

    RETVAL=0

    prog="rsync"

    #check if rsync is already running

    start(){

    if [ ! -f /var/run/rsyncd.pid ];then

    /usr/bin/rsync --daemon --config=/etc/rsyncd.conf

    fi

    return $RETVAL

    }

     

    stop(){

    killproc /usr/sbin/rsync

    RETVAL=$?

    [ $RETVAL -eq 0 ] && rm -f /var/run/rsyncd.pid

    }

    restart(){

    stop

    start

    }

    reload(){

    restart

    }

     

    case "$1" in

    start)

    action "starting $prog ......" /bin/true

    start

    ;;

    stop)

    action "stopping $prog ......" /bin/true

    stop

    ;;

    restart|reload)

    action "stopping $prog ......" /bin/true

    stop

    action "starting $prog ......" /bin/true

    start

    ;;

    *)

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

    exit 1

    esac

     

     

    19.天津抓阄项目

    企业面试题17:老男孩教育天津项目学生实践抓阄题目:

    好消息,老男孩培训学生外出企业项目实践机会(第6次)来了(本月中旬),但是,名额有限,队员限3人(班长带队)。

    因此需要挑选学生,因此需要一个抓阄的程序:

    要求:

    1、执行脚本后,想去的同学输入英文名字全拼,产生随机数01-99之间的数字,数字越大就去参加项目实践,前面已经抓到的数字,下次不能在出现相同数字。

    2、第一个输入名字后,屏幕输出信息,并将名字和数字记录到文件里,程序不能退出继续等待别的学生输入。

    我的方法

    #!/bin/sh

     

    while true

    do

    read -p "please input English name: " a

    if [ -z "$a" ];then

    continue

    else

    ran_num=`expr $RANDOM % 10`

    zhua_num=`cat /tmp/zhuajiu.log |grep "$ran_num"|awk ‘{print $NF}‘`

    if [ -z "$zhua_num" ];then

    echo "$a $ran_num"

    echo "$a $ran_num" >>/tmp/zhuajiu.log

    else

    echo "The $zhua_num is used by $a"

    sleep 1

    continue

    fi

    fi

    done

     

     

     

    谢迪(错误,能出现相同的数字)

    [root@mysql 19_shell]# cat t17.sh

    #!/bin/sh

     

    while true

    do

    read -p "pls input your english name:" name

    if [ -n $name ];then

    [ ! -f /opt/a.log ]&&touch /opt/a.log

    numb1=`expr $RANDOM % 100`

    numb2=`cat /opt/a.log |grep "$numb1"|awk ‘{print $NF}‘`

    while [ $numb1 -eq $numb2 ] 2>/dev/null

    do

    numb1=`expr $RANDOM % 100`

    numb2=`cat /opt/a.log|grep $numb1|awk ‘{print $NF}‘`

    done

    echo "you choose numb is $numb1"

    echo "$name $numb1" >>/opt/a.log

    fi

    done

     

     

    李想(也错)

    #!/bin/bash

    seq 1 99 > list

    while true

    do

    read -p "请输入您的姓名:" name

    if [ -z "$name" ];then

    continue

    fi

    while true

    do

    NUM=`expr $RANDOM % 100`

    awk ‘/^$NUM$/ {print NR}‘ list &>/dev/null

    N=`awk "/^$NUM$/ {print NR}" list`

    if [ ! -z "$N" ]

    then

    echo $N

    echo -e "$name\t$NUM" >> result.txt

    sed -i ${N}d list

    sleep 0.5

    else

    continue

    fi

    break

    done

    done

     

     

    20.破解MD5sum加密

    企业面试题18:老男孩linux企业面试题:

    已知下面的字符串是通过RANDOM随机数变量md5sum|cut -c 1-8截取后的结果,请破解这些字符串对应的md5sum前的RANDOM对应数字?

    21029299

    00205d1c

    a3da1677

    1f6d12dd

    890684b

    解答

    我的方法

    [root@gw md5]# vim pojie.sh

    #!/bin/sh

     

    array=(

    21029299

    00205d1c

    a3da1677

    1f6d12dd

    890684b

    )

     

    for n in {0..32767}

    do

    num=`echo $n|md5sum|cut -c 1-8`

    for i in ${array[*]}

    do

    if [ "$num" == "$i" ];then

    echo "$i $n"

    fi

    done

    done

     

    李想

    #!/bin/bash

    md5_opt=( 21029299

    00205d1c

    a3da1677

    1f6d12dd

    890684b

    )

    for((i=0;i<999999;i++));do

    for md5 in ${md5_opt[*]} ; do

    num_md5=`echo $i | md5sum | cut -c 1-8`

    if [ $md5 == ${num_md5} ] ; then

    echo $i $md5

    fi

    done

    done

     

    [root@gw md5]# sh pojie.sh

    00205d1c 1346

    1f6d12dd 7041

    a3da1677 25345

    21029299 25667

     

    21.检查网站地址是否正常

    企业面试题19:批量检查多个网站地址是否正常

    要求:shell数组方法实现,检测策略尽量模拟用户访问思路

    http://www.etiantian.org

    http://www.taobao.com

    http://oldboy.blog.51cto.com

    http://10.0.0.7

    curl -I -s -w "%{http_code}\n" www.baidu.com -o /dev/null

     

    我的方法

     

    #!/bin/sh

    . /etc/init.d/functions

     

    url=(

    http://www.etiantian.org

    http://www.taobao.com

    http://oldboy.blog.51cto.com

    http://10.0.0.7

    )

     

    main(){

    for i in ${url[*]}

    do

    curl_num=`curl -I -s -w "%{http_code}\n" -o /dev/null $i`

    #curl_num=`curl -o /dev/null -s --connect-timeout 5 -w "%{http_code}" $i`

    if [ "$curl_num" == "200" -o "$curl_num" == "301" ]

    then

    action "$i" /bin/true

    else

    action "$i" /bin/false

    fi

    done

    }

    main

     

     

     

    李想

    #!/bin/sh

    . /etc/init.d/functions

    url_list=(

    http://10.0.0.5

    http://www.baidu.com

    http://oldboy.blog.51cto.com

    http://10.0.0.19

    )

     

    check_url(){

    [ $# -ne 1 ] && exit 1

     

    curl -o /dev/null -s --connect-timeout 5 -w "%{http_code}" $1

    }

    main(){

    for ((i=0;i<${#url_list[*]};i++))

    do

    code=`check_url ${url_list[i]}`

    if [ "$code" != "200" -a "$code" != "301" ];then

    action "${url_list[i]}" /bin/false

    else

    action "${url_list[i]}" /bin/true

    fi

    done

    }

    main

     

     

    22.按字母,单词出现频率排序

    企业面试题20(中企动力):用shell处理以下内容

    1、按单词出现频率降序排序!

    2、按字母出现频率降序排序!

    the squid project provides a number of resources toassist users design,implement and support squid installations. Please browsethe documentation and support sections for more infomation

    按单词

    法1

    [root@gw tr]# cat a.log |tr " ,." "\n"|egrep -v "^$"|sort |uniq -c|sort -nr

    2 support

    2 squid

    2 and

    1 users

    1 toassist

    1 the

    1 sections

    1 resources

    1 provides

    1 project

    1 Please

    1 of

    1 number

    1 more

    1 installations

    1 infomation

    1 implement

    1 for

    1 documentation

    1 design

    1 browsethe

    1 a

     

     

    法2(李想)

    [root@lixiang scripts]# tr ‘{ |,|.}‘ ‘\n‘<1.txt|grep -v ‘^$‘|awk ‘{S[$1]++}END{for(i in S) printf "%-20s %-10s\n", i,S[i]}‘|sort -nrk 2

    support 2

    squid 2

    and 2

    users 1

    toassist 1

    the 1

    sections 1

    resources 1

    provides 1

    project 1

    Please 1

    of 1

    number 1

    more 1

    installations 1

    infomation 1

    implement 1

    for 1

    documentation 1

    design 1

    browsethe 1

    a 1

     

    按字母:

    方法1

    tr "{ |,|.}" "\n" <a.log|grep -v "^$"|awk -F "" ‘{for (i=1;i<=NF;i++) print $i}‘|sort|uniq -c|sort -nr

    19 s

    17 e

    16 o

    14 t

     

    方法2

    cat a.log|tr ‘ ‘ ‘\n‘|grep -o ‘\w‘|sort|uniq -c|sort -nrk1

    19 s

    17 e

    16 o

    14 t

    12 n

    12 i

    11 r

     

     

     

     

    方法3

    tr "{ |,|.}" "\n" <a.log |awk -F "" ‘{for(i=1;i<=NF;i++)array[$i]++}END{for(key in array)print array[key],key}‘|sort -rn

    19 s

    17 e

    16 o

     

    方法4

    tr "{ |,|.}" "\n" <a.log |awk -F "" ‘{for(i=1;i<=NF;i++)array[$i]++}END{for(key in array)print array[key],key|"sort -rn"}‘

    19 s

    17 e

    16 o

    14 t

    13 i

     

     

     

     

    [root@mysql oldboy]# cat word.txt

    abcde,fghg

    [root@mysql oldboy]# cat word.txt |grep -o "\w"

    a

    b

    c

    d

    e

    f

    g

    h

    g

    [root@mysql oldboy]# cat word.txt |grep -o "[a-z]"

    a

    b

    c

    d

    e

    f

    g

    h

    g

    [root@mysql oldboy]# cat word.txt |grep -o "[0-9a-zA-Z_]"

    a

    b

    c

    d

    e

    f

    g

    h

    g

     

    grep :

    -o : --only-matching

    Show only the part of a matching line that matches PATTERN.

    \w : 等同与[0-9a-zA-Z_]

    他可以把一条语句,分开为单个单词!!

     

    echo $str|awk ‘BEGIN{FS=""}{for(i=1;i<=NF;i++)if($i !~ /[., ]/)count[$i]++}END{for(key in count)print key,count[key]}‘

     

    cp拷贝隐藏文件需要加.*

     

     

     

    shell颜色


    前景色
    echo -e "\033[30m 黑色字oldboy trainning \033[0m"
    echo -e "\033[31m 红色字oldboy trainning \033[0m"
    echo -e "\033[32m 绿色字oldboy trainning \033[0m"
    echo -e "\033[33m 黄色字oldboy trainning \033[0m"
    echo -e "\033[34m 蓝色字oldboy trainning \033[0m"
    echo -e "\033[35m 紫色字oldboy trainning \033[0m"
    echo -e "\033[36m 天蓝字oldboy trainning \033[0m"
    echo -e "\033[37m 白色字oldboy trainning \033[0m"


    RED_COLOR=‘\E[1;31m‘
    GREEN_COLOR=‘\E[1;32m‘
    YELLOW_COLOR=‘\E[1;33m‘
    BLUE_COLOR=‘\E[1;34m‘
    RES=‘\E[0m‘

    man手册查看颜色man console_codes


    背景色
    echo -e "\033[40;37m 黑底白字 welcome to old1boy\033[0m"
    echo -e "\033[41;37m 红底白字 welcome to old2boy\033[0m"
    echo -e "\033[42;37m 绿底白字 welcome to old3boy\033[0m"
    echo -e "\033[43;37m 黄底白字 welcome to old4boy\033[0m"
    echo -e "\033[44;37m 蓝底白字 welcome to old5boy\033[0m"
    echo -e "\033[45;37m 紫底白字 welcome to old6boy\033[0m"
    echo -e "\033[46;37m 天蓝白字 welcome to old7boy\033[0m"
    echo -e "\033[47;30m 白底黑字 welcome to old8boy\033[0m"


    字背景颜色范围:40----49
    40:黑
    41:深红
    42:绿
    43:黄色
    44:蓝色
    45:紫色
    46:深绿
    47:白色
    字颜色:30-----------39
    30:黑
    31:红
    32:绿
    33:黄
    34:蓝色
    35:紫色
    36:深绿
    37:白色
    ===============================================ANSI控制码的说明
    \33[0m 关闭所有属性
    \33[1m 设置高亮度
    \33[4m 下划线
    \33[5m 闪烁
    \33[7m 反显
    \33[8m 消隐
    \33[30m -- \33[37m 设置前景色
    \33[40m -- \33[47m 设置背景色
    \33[nA 光标上移n行
    \33[nB 光标下移n行
    \33[nC 光标右移n行
    \33[nD 光标左移n行
    \33[y;xH设置光标位置
    \33[2J 清屏
    \33[K 清除从光标到行尾的内容
    \33[s 保存光标位置
    \33[u 恢复光标位置
    \33[?25l 隐藏光标
    \33[?25h 显示光标

     

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!