Linux 自动化执行命令

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

sshpass

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

安装:

yum install sshpass -y

使用:

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

示例:

# 远程执行命令
sshpass -p <password> ssh -o StrictHostKeyChecking=no <root>@<ip> "ls -al"
# 远程连接
sshpass -p <password> ssh -o StrictHostKeyChecking=no <root>@<ip>

expect

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

安装:

yum install -y expect

常用用法:

  • send: 用于向进程发送字符串
  • expect: 从进程接收字符串
  • spawn: 启动新的进程
  • interact: 允许用户交互,把控制权交给控制台,这个时候就可以手工操作了
  • expect eof: 这个与 spawn 对应表示捕获终端输出信息终止,类似于 if….endif

特别说明下:

  • send 命令接收一个字符串参数,并将该参数发送到进程中去,一般用来发送到 spawn 命令启动的进程中去。
  • expect 命令和 send 命令正好相反, expect 命令通常是用来等待一个进程的反馈。
  • expect 命令可以接收一个字符串参数,也可以接收正则表达式参数。一般用来等待 spawn 命令启动的进程的反馈。

示例:

使用 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 dev xxx@xx.xx.xx.xx:/gitrepo/xxx/$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
上一篇:postman测试 上传下载文件


下一篇:利用expect在bash实现自动完成ssh互相配置