菜单   case    select


从/etc/init.d/httpd里拷的一段
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        status -p ${pidfile} $httpd
        RETVAL=$?
        ;;
  restart)
        stop
        start
        ;;
 *)
        echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}"
        exit 1
esac

 

case  "chioce" in
 "var1" )
  command
 ;;
 "var2" )
  command
 ;;
 "var3" )
  command
 ;;
 * )
  command
 exit 1
esac


例一:输入一个键,判断是大写字母还是小写字母,还是数字,还是其它


while true
do
read -n 1 -p "请输入一个键值:" key
echo

case "$key" in
     [[:upper:]] )
                echo "你输入的是一个大写字母"
                ;;
     [[:lower:]] )
                echo "你输入的是一个小写字母"
                ;;
     [[:digit:]] )
                echo "你输入的是一个数字"
                ;;
     [[:punct:]] )
                echo "你输入的是一个标点符号"
                ;;
        * )
                echo "你输入的是其它"
        ;;
esac
done

 

使用read让用户输入它的名字,性别(对性别进行判断),年龄(判断是否有18岁成年)


#!/bin/bash

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

read -n 1 -p "请输入你的性别(M和W或m和w):" sex
echo


read -p "请输入你的年龄:" age
[ $age -ge 18 ] && a=1 || a=0


case "$sex" in
        M | m)
                case "$a" in
                        1 ) echo "$name先生" ;;
                        0 ) echo "$name小子" ;;
                esac
        ;;
        W | w)
                case "$a" in
                        1 ) echo "$name女士" ;;
                        0 ) echo "$name×××" ;;
                esac
        ;;
        * )
                echo "性别有误,请重新运行"
                exit 1
        ;;
esac

 


交互输入一个人名,选择性别,或者姓名,显示相应的人的资料


#!/bin/bash


echo -e  "your sex?\n[M]ale\n[F]emale"
read sex


case "$sex" in
        M|m )
                echo "先生好!"
        ;;
        F|f )
                echo "女士好!"
        ;;
        * )
                echo "选择错误!请重选"
                sh $0
esac

=========================================================

 

echo "=================================="
echo "          choose your sex         "
echo "          1-male                  "
echo "          2-female                "
echo "          0-exit                  "
echo "=================================="
echo -e "please enter your choice(0-2):\c "
read choice

case "$choice" in
        1 )
        clear
                echo "you are male"
        ;;
        2 )
        clear
                echo "you are female"
        ;;
        0 )
                exit 1
        clear
        ;;
        * )
                echo "invalid choice! please choose (0-2);"
        clear
esac

 

改写上一个题目,在case里面再嵌套case菜单,使之选项更丰富


while true
do
echo "=================================="
echo "          choose your sex         "
echo "          1-male                  "
echo "          2-female                "
echo "          0-exit                  "
echo "=================================="
echo -e "please enter your choice(0-2):\c "
read choice

case "$choice" in
        1 )
        clear
                echo "you are male"

        read -n 1 -p "are you a gay? y/n [n]:" answer1
                case "$answer1" in
                        Y|y) echo && echo 'oh,gosh';;
                        N|n) echo &&echo 'congratulations!';;
                        *)  echo &&echo 'what is your problem';;
                esac

        ;;
        2 )
        clear
                echo "you are female"

        read -n 1 -p "are you a lesbian? y/n [n]:" answer2
                case "$answer2" in
                        Y|y) echo && echo 'what a pity!';;
                        N|n) echo && echo 'Can i have your number';;
                        *)  echo && echo 'what is your problem';;
                esac

        ;;
        0 )
                exit 1
        clear
        ;;
        * )
                echo "invalid choice! please choose (0-2);"
        clear
esac
done


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


select  建立菜单选项的另一种工具,它是从ksh引进的

PS3="  "


select var in  choice1 choice2 choice3 ...
do
 echo "................."
done

 例五:用select做一个选择菜单

PS3="please choose what operation system you are using:" --PS3是select命令用来加入提示字符串的符号,(默认会使用#?)

echo

select os in  xp   vista   windows7 linux unix
do
        echo
        echo "your operation system is $os"
        echo
        break --这里不加break的话,就会一直循环让你选择
done

 

=========================================================

 


函数

function_name () {
  command
  command
}


function function_name () {
  command
  command
}

 


模拟用函数写一个服务启动,关闭,重启的脚本 (要求有start,stop,restart,status,支持chkconfig等功能) --提示:使用随机数来做pid文件


vim 5.sh


#!/bin/bash

# chkconfig: - 85 15
# description: This is a test program.


start () {
        [ -e /var/run/testd.pid ] && echo "already startd" && exit 1
        echo -n "starting testd:"
        for i in `seq 5`
        do
                echo -n "."
                sleep 1
        done
        echo -n "                   [OK]"
        echo
        echo $RANDOM > /var/run/testd.pid
}

stop () {
        echo -n "stopping testd:"
        for i in `seq 5`
        do
                echo -n "."
                sleep 1
        done
        echo -n "                   [OK]"
        echo
        [ -e /var/run/testd.pid ] && rm -rf /var/run/testd.pid
}

status () {
        [ -e /var/run/testd.pid ] && echo "testd (pid `cat /var/run/testd.pid`) is running..." || echo "testd is stopped"
}


case "$1" in
        start )
                start ;;
        stop )
                stop ;;
        restart )
                stop
                start ;;
        status )
                status ;;
        * )
                echo "USAGE:start|stop|restart|status"
        exit 1
esac


cp 5.sh /etc/init.d/testd
chmod 755 /etc/init.d/testd
chkconfig --add testd
chkconfig testd on --level 2345

 


read输入一个目录,找出目录下包括子目录下为死链接的文件。(要求不使用find,使用函数进行递归查找子目录里的文件)


#!/bin/bash

ckdeadlink () {
for i in $1/*
do
        [ -h $i -a ! -e $i ] && echo "$i为死链接"
        [ -d $i ] && ckdeadlink $i
done
}

read -p "输入一个目录:" dir
echo

ckdeadlink $dir


结合函数和case菜单功能,写一下关于usb挂载的脚本,(要实现的功能有挂载,卸载,列出挂载后内容,usb拷贝文件到系统,系统拷贝文件到usb,退出等六个功能)

 


#!/bin/bash

mountusb () {
        clear
        fdisk -l |grep sd
echo -n "请选择你的挂载的设备(写全名,如/dev/sdb1): "
        read dev
        mount $dev /mnt
}

umountusb () {
        clear
 cd /
        umount /mnt
        echo "卸载完成"
}

display () {
        clear
        ls -l /mnt
}

usbtosystem () {
        clear
        echo -n "选择你要拷的文件(写相对路径): "
        read file1
        echo -n "选择你要拷到哪个路径(写绝对路径): "
        read path1
        cd /mnt
        cp $file1 $path1/
}

systemtousb () {
        clear
        echo -n "选择你要拷的系统文件(写绝对路径): "
        read file2
        echo -n "选择你要拷到usb哪个路径(写绝对路径): "
        read path2
        cp $file2 $path2/
}

quit () {
        clear
        echo "##############"
        echo " 谢谢使用@_@ "
        echo "##############"
        exit 1
}


while true
do
echo "##################################"
echo "    usb mount program by li       "
echo "##################################"
echo "                                  "
echo "          1-挂载                  "
echo "          2-卸载                  "
echo "          3-列出内容              "
echo "          4-拷文件到系统          "
echo "          5-拷文件到usb           "
echo "          0-退出程序              "
echo "                                  "
echo "##################################"
echo -n "请选择(0-5): "
read choice

case "$choice" in
        1 ) mountusb ;;
        2 ) umountusb ;;
        3 ) display ;;
        4 ) usbtosystem ;;
        5 ) systemtousb ;;
        0 ) quit ;;
        * ) echo "只能选择0-5,请重新选择!";;
esac

done

 

=============================================


正则表达式

. 一个字符
.. 两个字符
^# 以#号开头
#$ 以#号结束
[abc] 包含a或b或c的都匹配
[^abc] 只要出现了abc这三个字母以外的字符就都匹配       --重点
a+ 匹配至少一个或多个a
a* 匹配0或多个a
a? 匹配0或1个a

 

大写 [[:upper:]]  [A-Z]
小写 [[:lower:]]  [a-z]
字母 [[:alpha:]] [a-Z] 
字母数字 [[:alnum:]]
空格或者制表符 [[:blank:]]
纯数字 [[:digit:]] [0-9]
标点符号 [[:punct:]]


========================================================


显示查出的行在原文件的行号加n参数 grep -n root /etc/passwd  
反向查找加v参数  grep -v bin /etc/passwd
大小写不敏感加i参数  grep -ni root grep.txt

 

查找出有rot或者是rat的行 grep -n r[oa]t grep.txt --注意的是,[ ]括号内不论几个字符,都是选一个

查找一个非r字符加oot连在一起的行 grep  '[^r]oot' grep.txt

查找不以小写字母开头  grep  '[^a-z]oo' grep.txt  

--记住: [] 里的^为取反   ,外面的为以它开头


[root@dns shell03]# grep  '^[a-z]oot' grep.txt
root
boot
[root@dns shell03]# grep  '[^a-z]oot' grep.txt   --表示有一个非小写字符连着oot的就会被找出来
Root
Boot

 

 

[root@li test]# cat test
root
Root
rot
boot
Rot
[root@li test]# grep '[^A-Z]o' test   --查找不以大写字母的一个字符连着一个o
root
Root
rot
boot
[root@li test]# grep '[^A-Z]oo' test  --查找不以大写字母的一个字符连着两个o
root
boot
[root@li test]# grep '^[^A-Z]' test --这等同于不以大写字母开头(但可以以小写,数字,或空格等开头)
root
rot
boot

 

查找不以大写字母开头   grep '[^[:upper:]]' grep.txt
   grep  '^[^A-Z]' grep.txt


查找有数字的号   grep '[0-9]' grep.txt
  或者 grep [[:digit:]] grep.txt


查找一个数字和一个字母连起来的行

   grep '[0-9][a-Z]' grep.txt

行首^    行尾$

查找不以r开头的   grep -v ^r grep.txt

 

查找以数字开头的   grep ^[0-9]  grep.txt
  grep ^[[:digit:]] grep.txt


查找以大写字母开头的 grep ^[A-Z] grep.txt 或者 grep ^[[:upper:]] grep.txt
查找以小写字母开头的 grep ^[a-z] grep.txt 或者 grep ^[[:lower:]] grep.txt

查找以点结束的   grep "\."$ grep.txt  --注意要引起来,而且要转义


去掉空格行    cat  grep.txt  |grep -v ^$ --以^$表示空格行


查找完全匹配abc的  grep  ^abc$ grep.txt


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


.  点号代表一个任意字符
*  代表零个或者多个前字符
.*  代表0个或多个任意字符


[root@li test]# cat grep.txt
ggle
gogle
google
gooogle
gagle
gaagle
gaaagle
abcgef
abcdef


比较:
grep 'g.g' grep.txt  --只要两个g字母中间有一个任意字符就可以
grep 'g*g' grep.txt --只要有一个g字母就可以。等同于grep g grep.txt
grep 'go*g' grep.txt    --只要两个g字母中间有零个o或多个o就可以
grep 'g.*g' grep.txt --只要两个g字母中间有零个或任意个字符就可以
grep 'go.*g' grep.txt  --只要go与g字母中间有零个或任意个字符就可以 

 

 

==================================================================


expect   自动应答  TCL语言


yum install expect -y


Summary     : A program-script interaction and testing utility
Description :
Expect is a tcl application for automating and testing
interactive applications such as telnet, ftp, passwd, fsck,
rlogin, tip, etc. Expect makes it easy for a script to
control another program and interact with it.

This package contains expect and some scripts that use it.

 

例一:使用自动应答修改用户密码

#!/bin/bash

expect <<EOF > /dev/null 2>&1
spawn passwd $1  --产生passwd $1这个命令
expect "rd:"  --当停在rd:结尾这个标识符时
send "456\r"  --我就把456传给它
expect "rd:"  --当再次停在rd:结尾这个标识符时
send "456\r"  --我就再次把456传给它
expect eof  --表示expect结束
EOF


# sh 8.sh user2    --执行方法,因为脚本里写的是$1,所以后面接你要修改密码的用户名


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

#!/bin/bash


sed -i "/^2.2.2.95/d" /root/.ssh/known_hosts
expect << EOF > /dev/null 2>&1
spawn ssh 2.2.2.95
expect "no)?"
send "yes\r"
expect "password:"
send "123456\r"
expect "]#"
send "mkdir /root/Desktop/test\n"
send "touch /root/Desktop/test/{1..10}\n"
send "exit\n"
expect eof
EOF


# sh 9.sh  --执行方法


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

#!/usr/bin/expect

set host [lindex $argv 0]
set user [lindex $argv 1]
set passwd [lindex $argv 2]

spawn ssh $user@$host
expect "password:"
send "$passwd\r"
expect "]#"
send "touch /root/Desktop/abc\n"
send "exit\n"


# sh 10.sh 2.2.2.95 root 123456   --这样执行是错误的。因为sh命令就是直接调用bash去解释,不管你脚本开头定义的#!/usr/bin/expect

# chmod 755 10.sh
# ./10.sh 2.2.2.95 root 123456   --正确执行方法

 


====================================================

题目:


用read输入一个文件,然后把行数倒序输出(上下倒序),保存到一个新文件

#!/bin/bash

read -p "input a filename:" file

[ -e /tmp/reserve.txt ] && rm -rf /tmp/reserve.txt

line=`cat $file | wc -l`

for (( i=$line;i>0;i-- ))
do
        echo `head -$i $file | tail -1` >> /tmp/reserve.txt
done

 

使用read输入一个整数,把数字中的所有数字转换成英文单词
 如:2345  转换为 two three four five

提示:需要计算输入的整数的长度,然后进行循环,截取整数中的单一字符(man cut),对截取的单一字符使用case菜单分类,最后打印


#!/bin/bash

read -p "输入一个整数:" num

length=`echo $num |wc -c`
length=$[$length-1]

for (( i=1;i<=$length;i++ ))
do
        n=`echo $num |cut -c $i`
        case "$n"  in
                0 ) echo -n "zero " ;;
                1 ) echo -n "one " ;;
                2 ) echo -n "two " ;;
                3 ) echo -n "three " ;;
                4 ) echo -n "four " ;;
                5 ) echo -n "five " ;;
                6 ) echo -n "six " ;;
                7 ) echo -n "seven " ;;
                8 ) echo -n "eight " ;;
                9 ) echo -n "nine " ;;
        esac
done

 

使用expect实现自动ftp登录下载我的笔记
登录方法:
lftp 2.2.2.35 -u ule
密码为123


#!/usr/bin/expect


spawn lftp 2.2.2.35 -u ule 
expect "password:"
send "123\r"
expect ":~>"
send "mirror shell /root\n"
send "quit\n"