shell---if,case,expect

if语句

 if 效率低,从上往下执行
语句格式:
if
then
elif
then
。。。
else
fi   ##语句结束

简单的示例:
【1】只有if,then,fi

vim /mnt/test.sh  
    if [  -z "$1" ]
    then
   		   echo -e "\033[31mPlease input filename following $0!!!\033[0m"
    exit 1
    fi
    sh  /mnt/test.sh
    sh /mnt/test.sh file

在这里插入图片描述
在这里插入图片描述
【2】只有if,then,elis,fi

vim  /mnt/test.sh 
  #!/bin/bash
  if [  -z "$1" ]
  then
      echo -e "\033[31mPlease input filename following $0!!!\033[0m"
      exit 1
  elif [ -e "$1" ]
  then
      echo "$1 is exist"
      exit 0
  fi
sh /mnt/test.sh
sh /mnt/test.sh
sh /mnt/test.sh westos

vim /mnt/test.sh
在这里插入图片描述
在这里插入图片描述
【3】加入else

 vim /mnt/test.sh 
   #!/bin/bash
   if [  -z "$1" ]
   then
       echo -e "\033[31mPlease input filename following $0!!!\033[0m"
       exit 1
    elif [ -e "$1" ]
    then
        echo "$1 is exist"
    exit 0
    else            ##除了以上情况外,输入以下内容
    echo "$1 is directory"
    fi
 sh /mnt/test.sh
 sh /mnt/test.sh westos 
 sh /mnt/test.sh hello

在这里插入图片描述
在这里插入图片描述

练习1:

 判断
先判断$1是否存在;
存在的时候,再判断类型
目录,文件,链接
每次判定完以后,输入exit(无论大小写),退出
[root@localhost mnt]# checkfiletype.sh \
> Please input filename: /mnt \
> /mnt is directory \
> /mnt is not exist \
> Please input filename: exit \
> bye
步骤:
vim /mnt/checkfiletype.sh
  #!/bin/bash
  while true
  do
      read -p "Please input filename [or exit or quit]: " NAME
      if [ "$NAME" = "EXIT " -o "$NAME" = "exit" ]
      then
              echo bye~~~
              exit 0
      elif [ -L "$NAME" ]
      then
             echo "$NAME is softlink file"
      elif [ -d "$NAME" ]
      then
        echo "$NAME is directory!"
      elif [ -f "$NAME" ]
      then
              echo "$NAME is common file"
      else
              echo "$NAME is not exist!!!"
      fi
  done
sh /mnt/checkfiletype.sh

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

练习2:

 当执行filectrl -a  file
          -d 删掉
          -p 备份到/mnt目录下
 	什么都不是,则报错
vim  /mnt/filectrl.sh
内容:
#!/bin/bash
Check_File()    【1】
{
    if [ -e "$1" ]
    then
            $2     ##相当于【2】"echo $2 is exist !" 
            $3     ##相当于【2】exit
    fi 
}
if [ "$#" -lt "2" ]
then
    echo -e  "\033[31mError:Please input option [-a|-d|-p] and following filename $0:\033[0m"
    exit 1 
elif [ "$1" = "-a" ]
then
    Check_File $2 "echo $2 is exist !" exit   【2】
    touch $2
elif [ "$1" = "-d" ]
then
    Check_File $2 "rm -fr $2" exit
    echo "$2 is not exist"
elif [ "$1" = "-p" ]
then
     Check_File $2 "cp -rp $2 /mnt" exit
     echo "$2 is not exist!!!"
else
     echo "Please input option [-a|-d|-p] following $0!!"
fi

 测试:
  sh /mnt/filectrl.sh -a file
  sh /mnt/filectrl.sh -d file
  sh /mnt/filectrl.sh -p /etc/passwd
  ls  /mnt

在这里插入图片描述
在这里插入图片描述

case

 Case 和 if
 Case是点名机制,只判断一次速度快,做整体对比,进行匹配
 if每次都会判断
 case
 esca

易懂的示例:

 cd  /mnt 
vim case.sh

#!/bin/bash
case $1 in
    westos)
    echo linux
    ;;
    linux)
    echo redhat
    ;;
    redhat)
    echo westos
    ;;
    *)    ###输入其他,显示错误
    echo Error
esac
sh case.sh westos
sh case.sh linux
sh case.sh redhat
sh case.sh haha

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

##练习3:在练习2 的基础上修改

vim  filectrl.sh

#!/bin/bash
Check_File()       ##添加一个函数
{
    if [ -e "$1" ]
    then
            $2
            $3
    fi
}
if [ "$#" -lt "2" ]
then
    echo "Error:Please input option [-a|-d|-p] and following filename $0"
    exit 1
fi

case $1 in
    -a|a|-A|A)
    Check_File $2 "echo $2 is exist !" exit
    touch $2
    ;;
    -d|d|-D|D)
    Check_File $2 "rm -fr $2" exit
    echo "$2 is not exist"
    ;;
    -p|p|-P|P)
    Check_File $2 "cp -rp $2 /mnt" exit
    echo "$2 is not exist"
    ;;
    *)
    echo "Please input option [-a|-d|-p] following $0!!"
esac

测试:
  sh /mnt/filectrl.sh -a file
  sh /mnt/filectrl.sh -d file
  sh /mnt/filectrl.sh -p /etc/passwd
  ls  /mnt

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
expect

expect :是自动应答命令用于交互式命令的自动执行
spawn :是expect中的监控程序,其运行后监控命令提出的交互问题
send :发送问题答案给交互命令
"\r":表示回车
 exp_continue ##表示当问题不存在时继续回答下面问题
expext eof :表示问题回答完毕退出expect环境
interact: 表示问题回答完毕留在交互界面,适用于远程登陆
set NAME [ lindex $argv n ]  ##定义变量 ,从0开始计数(对于不固定答案)
			即执行 expect /mnt/answer.exp 后跟的第n个参数
			例如: 看【2】 expect /mnt/answer.exp hedan
 expect file.exp    ##运行
只有#!/usr/bin/expect
才能识别spawn

远程登陆的时候用到interact
set timeout 5  : 等待5妙,没反应直接跳过

先做几个简单例子来理解:
问问题的脚本:

 cd /mnt
 vim   ask.sh
 #!/bin/bash
 read -p "What is you name: " NAME
 read -p "HOW old are you: " AGE
 read -p "Which object you study: " CLASS
 echo $NAME is $AGE old study $CLASS
sh  ask.sh  ##运行脚本输入答案

yum install expect -y    ##安装自动应答交互式服务
vim /mnt/answer.exp
内容:
  #!/usr/bin/expect    ##此路径才能时别spawn
  spawn /mnt/ask.sh    ##监控此脚本
  expect "name"        ##挑明显的问题 name
  send "hedan\r"       ##发送的应答
  expect "old"
  send "20\r"
  expect "object"
  send "Linux\r"
  expect eof          ##结束此环境
  
chmod +x ask.sh
expect answer.exp   ##运行

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
vim /mnt/answer.exp
在这里插入图片描述
在这里插入图片描述
【1】脚本中:监控问题脚本,发送应答

vim /mnt/answer.exp
 #!/usr/bin/expect
 spawn /mnt/ask.sh
 expect {
      "name"          { send  "hedan\r";exp_continue }
      "old"           { send  "20\r";exp_continue }
      "object"        { send  "linux\r" }    ##此问题是最后一个问题,所以不需要exp_continue
 }
 expect eof 
chomd +x /mnt/answer.exp
/mnt/answer.exp     ##运行脚本,显示问题与相应的答案

vim /mnt/answer.exp
在这里插入图片描述
在这里插入图片描述
【2】定义变量;对于不固定的应答

vim /mnt/answer.exp

 #!/usr/bin/expect
 set NAME [ lindex $argv 0 ]  (1) ###定义变量
 spawn /mnt/ask.sh
 expect {
      "name"          { send  "$NAME\r";exp_continue }  (2)   
      "old"           { send  "20\r";exp_continue }
      "object"        { send  "linux\r" }
 }
 expect eof
 /mnt/answer.exp  yibo  (3) ##则问题NAME应答为 yibo 
详解: (1)中的 0 是(3)命令后的第一个参数yibo,(2)中的$NAME就是 (1)中的NAME,发送$NAME,即收到应答为yibo

vim /mnt/answer.exp
在这里插入图片描述
在这里插入图片描述
【2】的延伸

vim /mnt/answer.exp
内容:
#!/usr/bin/expect
set NAME   [ lindex $argv 0 ]        ##命令后的第一个变量参数
set OLD    [ lindex $argv 1 ]        ##同上,第二个变量
set OBJECT [ lindex $argv 2 ]
spawn /mnt/ask.sh
expect {
      "name"          { send  "$NAME\r";exp_continue }
      "old"           { send  "$OLD\r";exp_continue }
      "object"        { send  "$OBJECT\r" }
}
expect eof
/mnt/answer.exp  yibo 20 dance    ##显示yibo is 20 old study dance

vim /mnt/answer.exp
在这里插入图片描述
在这里插入图片描述

以下可以很好的区别 interact 和 expect eof
【3】 :练习

要求:
 执行 ( /mnt/answer.exp 172.25.254.ip  密码pass  )后自动连接此主机

(1)停留在交互式界面: interact

vim /mnt/auto_ssh.exp
内容:
#!/usr/bin/expect
set timeout 5
set IP     [ lindex $argv 0 ]
set PASS   [ lindex $argv 1 ]
spawn ssh root@$IP
expect {
      "yes/no"     { send "yes\r";exp_continue }
      "password"   { send "$PASS\r" }
}
interact

chmod +x  /mnt/auto_ssh.exp
auto_ssh.exp 172.25.254.12  westos

vim /mnt/auto_ssh.exp
在这里插入图片描述
在这里插入图片描述

(2)退出expect环境:expect eof

vim /mnt/auto_ssh.exp
内容:
#!/usr/bin/expect
set timeout 5
set IP     [ lindex $argv 0 ]
set PASS   [ lindex $argv 1 ]
spawn ssh root@$IP
expect {
    "yes/on"     { send "yes\r";exp_continue }
    "password"   { send "$PASS\r" }
}
expect eof
auto_ssh.exp 172.25.254.12  westos  ##连接到12以后,我自己的网络问题,等待几秒又退回到112主机     ,一般情况下,直接退出到当前环境

vim /mnt/auto_ssh.exp
在这里插入图片描述
在这里插入图片描述

【4】添加连接的主机名称hostname

vim /mnt/auto_ssh.exp 
#!/usr/bin/expect
set timeout 5
set IP           [ lindex $argv 0 ]
set PASS         [ lindex $argv 1 ]
spawn ssh root@$IP hostname
expect {
    "yes/no"     { send "yes\r";exp_continue }
    "password:"  { send "$PASS\r" }
}
interact

chmod +x /mnt/auto_ssh.exp 
/mnt/auto_ssh.exp 172.25.254.62 westos
/mnt/auto_ssh.exp 172.25.254.62 westos | tail -n 1  ##截取连接的主机的主机名称

vim /mnt/auto_ssh.exp
在这里插入图片描述
在这里插入图片描述
整合shell,expect环境

在shell环境中不能用expect的脚本格式,
以下将两个环境组合在一起,整合在shell里面,这样在shell环境中就能用expect的格式
expect 路径:/usr/bin/expect

在这里插入图片描述
练习:
【1】找出连接的主机的名称,并退出环境 (先用指定的ip 172.25.254.62为示例)

vim auto_ssh.exp
 #!/bin/bash
 Auto_Connect()
 {
 /usr/bin/expect <<EOF    ##在此处需要顶格写
 spawn ssh root@$1 $2
 expect {
 "yes/no"     { send "yes\r";exp_continue }
 "password:"  { send "westos\r" }
 }
 expect eof
 EOF
 }
 Auto_Connect 172.25.254.62 hostname | tail -n 1
 /mnt/auto_ssh.sh

vim auto_ssh.exp
在这里插入图片描述
在这里插入图片描述
【2】在【1】的基础上将ip改为变量

vim auto_ssh.sh
内容:
#!/bin/bash
Auto_Connect()
{
/usr/bin/expect <<EOF        ##expect的路径
spawn ssh root@$1 $2
expect {
"yes/no"     { send "yes\r";exp_continue }
"password:"  { send "westos\r" }
}
expect eof
EOF
}
Auto_Connect $1  hostname | tail -n 1
/mnt/auto_ssh.sh  172.25.254.62         ##$1即为此处的ip

vim auto_ssh.sh
在这里插入图片描述
在这里插入图片描述
练习【1】:
执行/mnt/auto_ssh.sh
将开着的主机名导入host_list

 ^M(ctrl + v  ; ctrl + m )            
 思路: (1)检验哪些主机是开着的,即是否可以ping通
      (2)然后 ssh 连接可以ping通的主机
      (3)将ssh上的主机名截取

步骤:

 vim /mnt/auto_ssh.sh
内容:
#!/bin/bash
Auto_Connect()
{
/usr/bin/expect <<EOF
spawn ssh root@$1  $2
expect {
"yes/no"   { send "yes\r";exp_continue }
"password" { send "westos\r" }
}
expect eof
EOF
}
for NUM in {2..8}         ##最好确保在这个范围内的主机密码都是westos
do
    ping -c1 -w1 172.25.254.$NUM &> /dev/null      ##检验哪些主机可以ping通
    if [ "$?" = "0" ]
    then
          Auto_Connect 172.25.254.$NUM  hostname | tail -n 1 >> /mnt/host_list
    fi
done

chmod +x /mnt/auto_ssh.sh
/mnt/auto_ssh.sh

vim /mnt/auto_ssh.sh
在这里插入图片描述
在这里插入图片描述

练习【2】在远程登录的主机上建立用户密码:

/mnt/create_user.sh
userlist
passlist

思路:
1:先检验网络是否通畅,即是否可以ping通
2: 在ping通的主机上做,自动登陆,远程主机,
3:然后在远程的主机中建立用户密码

 用户列表:
 cat userlist
 use1
 use2
 use3
 cat passlist
 use123
 uer456
 use789

脚本:

vim  create1_user.sh
#!/bin/bash
Auto_Connect()  ##写入一个函数,远程连接主机
{
/usr/bin/expect <<EOF
spawn ssh root@$1  $2
expect {
"yes/no"   { send "yes\r";exp_continue }
"password" { send "westos\r" }
}
expect eof
EOF
}

Max_Line=`awk 'BEGIN{N=0}{N++}END{ print N}' $1`  ##文件的行数
for NUM in {2..8}       ##172.25.254.2--172.25.254.8
do
    ping -c1 -w1 172.25.254.$NUM &> /dev/null  ##检验哪些主机可以ping通
    if [ "$?" = "0" ]
    then
            for User_NUM in `seq 1 $Max_Line`    ##以下是将两个文件的内容相匹配为用户和密码
            do
                    USERLIST=`sed -n ${User_NUM}p $1`
                    PASSLIST=`sed -n ${User_NUM}p $2`
                    Auto_Connect 172.25.254.$NUM  "id $USERLIST &> /dev/null || useradd $USERLIST && echo $PASSLIST | passwd --stdin $USERLIST" &> /dev/null
            done
    fi
done
   /mnt/create1_user.sh userlist passlist  

解析:

 id $USERLIST ##检测$USERLIST用户是否存在
(1) 若存在则不执行 || 后面的命令 
(2) 若用户不存在,则执行 || 后面的建立用户和设置密码

测试:

 ssh root@172.25.254.3
  su - use1
  su - use2
  su - use3

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值