2018-09-28 · Tools

Linux 下自动化脚本的交互命令

我们经常需要进行一些自动化,定时运行的脚本时。
经常会需要我们手动输入的情况。为了绕过这些交互式的验证。我选择使用 sshpassexpect 来解决。

sshpass

sshpass 是一个简单、轻量级的命令行工具,通过它我们能够向命令提示符本身提供密码(非交互式密码验证)。

安装:

yum install sshpass -y

使用:

sshpass -p password ssh -o StrictHostKeyChecking=no username@password "command"

示例:

sshpass -p password ssh -o StrictHostKeyChecking=no root@password "ls -al"

expect

expect是基于TCL的相对简单的一个免费脚本编程工具语言,用来实现自动和交互式任务进行通信,无需人的手工干预。

安装:

yum install -y expect

常用用法:

特别说明下:

示例:

使用 expect 来远程登陆 ssh

#!/usr/bin/expect
# 告诉系统使用那个shell来执行文件

set timeout 30
# 设置超时时间的秒数, timeout -1 为永不超时

set HOST [lindex $argv 0]
# 将第一个参数赋值给HOST变量

set PASSWORD [lindex $argv 1]
# 将第二个参数赋值给PASSWORD变量

spawn ssh root@$HOST
# 启动新的进程,该进程使用 root 账号 ssh 远程登陆 $HOST 地址

expect {
    "yes/no" {
        send "yes\r";
        exp_continue
    }
    "password:" {
        send "$PASSWORD\r"
    }
}

# 多分支等待ssh进程的反馈
# 如果字符串中包含 yes/no 时,执行分支一
# 如果字符串中包含 password: 时,执行分支二
# 其中 exp_continue 附加于某个 expect 判断项之后,可以使该项被匹配后,还能继续匹配该 expect 判断语句
# 关于 \r 是因为 expect的字符处理是没有换行符之类的,所以需要额外加上

expect "*#"
send "ll -a\r"
# 以上两句是单分支匹配到 # 时执行 ll -a

expect eof
exit
# expect eof和exit是指监测到eof就会执行exit,退出程序。

在 bash 中嵌套使用 expect ,示例中进行 maven 自动打包

#!/usr/bin/env bash

DIR_LIST=("module1" "module2" "module3" "module_build" "module4" "module5")
PASSWORD="password\r"

for dir in ${DIR_LIST[@]}
do
    # echo $dir
    if [ -d "$dir" ]; then
        rm -rf "$dir"
    fi
    GIT_URL="git clone -b enms-dev zuojl@135.251.99.106:/gitrepo/enms/$dir"
    # echo $GIT_URL
    /usr/bin/expect <<-EOF
    set timeout -1
    spawn $GIT_URL
    expect "*password:"
    send $PASSWORD
    expect eof
    EOF
    echo -e "\n"
done

sleep 1

mvn clean install -f module_build/ -Dmaven.test.skip=true