1.1  shell一些小总结

    1, 零宽断言
    2, 打印菜单 
    3, getopts选项简介
    4, 脚本查询ip地理位置

1.1.1  grep  Zero-Width Assertions (零宽断言)

 意思就是取出得到你想要的东西,去掉你不关心的东西

    -o: 表示精确匹配
    -P: 表示使用pcre的正则表达式进行匹配

    1.先行断言: 表示匹配表达式前面的位置

[root@bj-idc-15 ~]# echo "cooking sing" | grep -oP '[a-z]*(?=ing)'   
cook
s

    上面例子:  (?=ing) 这个就是断言,意思当这个断言存在的时候,进行判断匹配,匹配到的

    对象是它前面的字符串.当然前面的字符串你也需要用正则表达式匹配,例如:([a-z])*,由于

    正则是贪婪的,所以断言会一直从右面匹配到不能匹配的时候结束.

    

    2.后发断言: 表示匹配表达式后面的位置

[root@bj-idc-15 ~]# echo "abcdefg  abca" | grep -oP '(?<=abc).*'    
defg  abca

    上面的例子: (?<=abc)为断言,跟上面的相反,它是从最左端开始匹配

小小实战

(1)取ip地址

[root@bj-idc-15 learn]# ifconfig 
eth0      Link encap:Ethernet  HWaddr 06:66:91:E7:9A:74  
          inet addr:10.10.11.15  Bcast:10.10.11.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1234086 errors:0 dropped:0 overruns:0 frame:0
          TX packets:829131 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1182619038 (1.1 GiB)  TX bytes:88948632 (84.8 MiB)
          Interrupt:246 
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:62861848 errors:0 dropped:0 overruns:0 frame:0
          TX packets:62861848 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:10133085846 (9.4 GiB)  TX bytes:10133085846 (9.4 GiB)


取出em1的ip地址

[root@bds01 ~]# ifconfig | grep -E '(eth0|em1)' -A 1|grep -oP '(?<=addr:)[\d.]+'
10.10.10.180

(2)取日志的时间

假如nginx备份日志的格式文件是access_20150408_nginx.log

[root@bj-idc-15 ~]# echo "access_20150408_nginx.log" | grep -oP '(?<=access_).*(?=_nginx)'
20150408


1.1.2 打印菜单

echo命令

   

 -n: 不自动换行
  -e: 打开反斜杠ESC转义。若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出

          

            \a 发出警告声;
           \b 删除前一个字符;
           \c 最后不加上换行符号;
           \f 换行但光标仍旧停留在原来的位置;
           \n 换行且光标移至行首;
           \r 光标移至行首,但不换行;
           \t 插入tab;
           \v 与\f相同;
           \\ 插入\字符;
           \nnn 插入nnn(八进制)所代表的ASCII字符

read命令

 

     -p: 交互式显示提示符信息
    -t: 超时时间
    -n: 设定字符个数
    -s: 不会显(输入密码的时候有用)               
     -d: 定界符


实现一个简单菜单

#!/bin/bash
MYDATE=`date +%d/%m/%Y`
THIS_HOST=`hostname`
USER=`whoami`
while true;do  
#clear
cat <<EOF
        ____________________________________________________
                User: $USER Host: $THIS_HOST DATE: $MYDATE 
        ____________________________________________________
                1: list files 
                2: See memory total 
                3: See who is on the systeme 
                4: Help screen 
                Q: Exit Menu 
        ____________________________________________________
EOF
echo -e  -n "\t You Choice[1,2,3,4,Q]> "
read CHOICE
echo $CHOICE
case $CHOICE  in 
1) ls ;; 
2) free -m ;;  
3) who ;; 
4) echo "This is help screen , nothing here yet to help you !" ;;
Q|q) exit 0 ;;
*) 
echo -e "\t \007 unknown user reponse" 
;;
esac 
#echo -e -n "\t Hit the return key to continue " 
read -p "  Hit the return key to continue " go
done

1.1.3 getopts简介

根据参数进行不同的提示或者不同的执行

先来看一个列子

#!/bin/bash 
while getopts "h:n:a" arg
do
        case $arg in 
                h)
                        echo "Welcome to Beijing arg:$OPTARG";;
                n) 
                        echo "Your name is $OPTARG";;
                a)
                        echo "Your age is $OPTARG" ;;
                :) 
                        echo "The -h arg must have one args";;
                ?) 
                        echo "Please input your select args" ;;
        esac 
done

执行结果

[root@bj-idc-15 learn]# sh get.sh -h "hello world" -n budongshu -a 18 
Welcome to Beijing arg:hello world
Your name is budongshu
Your age is

getopts的脚本使用方法

脚本.sh  option_string  variable

第一个参数使用-h 这样的选项 第二参数是-h 后面跟的hello world 字符串

解析上面的示例 

定义选项:

     可以看到while getopts "h:n:a" arg 这句,所以定义的选项"h:n:a"在这里定义. 

冒号含义

    1,字母后面跟上冒号代表这个选项必须有参数也就是-h和-n 后面必须提供一个参数,

        参数的值存储在变量$OPTARG

    2,字母后面没有冒号代表这个选项可以不用跟上参数 ,跟上也不进行赋值. 可以看到-a 没有值

    3, 在字母的最前面加上冒号代表忽略这个命令自己提供的错误信息提示. 下面演示一下


脚本

#!/bin/bash 
while getopts "h:n:a" arg
do
        case $arg in 
                h)
                        echo "Welcome to Beijing arg:$OPTARG";;
                n) 
                        echo "Your name is $OPTARG";;
                a)
                        echo "Your age is $OPTARG" ;;
     
                ?) 
                        echo "Please input your select args" ;;
        esac 
done

执行结果: 命令内部自己提供的报错中间那个

[root@bj-idc-15 learn]# sh get.sh -h hello -n  
Welcome to Beijing arg:hello
get.sh: option requires an argument -- n
Please input your select args

加上冒号以后再看

脚本

#!/bin/bash 
while getopts ":h:n:a" arg
do
        case $arg in 
                h)
                        echo "Welcome to Beijing arg:$OPTARG";;
                n) 
                        echo "Your name is $OPTARG";;
                a)
                        echo "Your age is $OPTARG" ;;
     
                ?) 
                        echo "Please input your select args" ;;
        esac 
done

执行结果: 可以看到少了一条报错.

[root@bj-idc-15 learn]# sh get.sh -h hello -n  
Welcome to Beijing arg:hello
Please input your select args

报错信息提示

脚本

#!/bin/bash 
while getopts ":h:n:a" arg
do
        case $arg in
                h)
                        echo "Welcome to Beijing arg:$OPTARG";;
                n)
                        echo "Your name is $OPTARG";;
                a)
                        echo "Your age is $OPTARG" ;;
                :) 
                        echo "The -h arg must have one args";;
                ?)
                        echo "Please input your select args" ;;
        esac
done

:  case中冒号,当你忽略系统命令报错的时候(就是在前面加上:号),还有参数-h后面有冒号的,代表必须跟上一个选项参数, 如果没有跟选项参数时候, 它会提示对应你自定义的错误信息,-a不是必须提供参数选项(因为字母后面没有加冒号),所以执行脚本的时候 -a 后面不跟参数(或者不跟-a 选项时候),也不会报错的

?  case中问号,当跟上的参数比如说-e 不存在的时候报错

以上所有的报错$OPTARG变量都是不可用的


1.1.4 脚本查询ip地理位置


脚本

#!/bin/bash
Getip=$(curl -s ip.cn?ip=$1)
IParea=$(echo $Getip|awk -F ":" '{print $3}'|awk '{print $1}')
IPisp=$(echo $Getip|awk -F ":" '{print $3}'|awk '{print $2}')
if [ ! $1 ];then
IP=$(echo $Getip|awk -F ":" '{print $2}'|awk '{print $1}')
echo $IP $IParea $IPisp
else
echo $1 $IParea $IPisp
fi

执行结果

[root@bj-idc-15 script]# ./getip.sh (当前的外网ip地址)   
117......... 北京市 ....
[root@bj-idc-15 script]# ./getip.sh 8.8.8.8
8.8.8.8 美国 Google
[root@bj-idc-15 script]# ./getip.sh 114.114.114.114
114.114.114.114 江苏省南京市 信风网络

2.0 Expect 简介

安装

yum install expect -y


脚本

#!/usr/bin/expect -f 
set ip [lindex $argv 0]   
set password "111111"
spawn ssh root@$ip
set timeout 20 
expect  { 
        "yes/no" { send "yes\r";exp_continue } 
        "password:" { send "$password\r" }
}
expect "]#"
send "free -m\r" 
interact
#expect eof 
#exit

执行结果

[root@bj-idc-15 learn]# hostname 
bj-idc-15
[root@bj-idc-15 learn]# ./test1.exp 10.10.10.14 
spawn ssh root@10.10.10.14
root@10.10.10.14's password: 
Last login: Mon Apr 11 16:24:49 2016 from 10.10.11.15
[root@BS01 ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          7870       2782       5088          0        341       2219
-/+ buffers/cache:        220       7650
Swap:         3999         57       3942
[root@BS01 ~]# hostname 
BS01