使用 Expect 制作自动部署脚本

使用Webpack以及Maven将项目打包后需要将其上传到服务器,每次手动操作非常麻烦,使用热部署也不太符合我的使用习惯,于是发现 Linux 上有 expect 这个神程序。

# Expect

Expect 是一个帮助你进行自动化交互(telnet、ftp、passwd……)的工具。Expect 对于测试这些相同的应用程序也是有用的。通过添加Tk,还可以在X11 GUI中封装交互式应用程序。

Expect 可以轻松地完成任何其他任务都非常困难的任务。您会发现 Expect 是一个绝对无价的工具——使用它,您将能够自动执行以前从未想到的任务——并且您将能够快速且容易地实现自动化。

# 基本语法

  • spwan 该命令用于新建一个新的进程
  • expect 该命令用户指令期望收到的字符串
  • send 该命令用于向进程发送字符串
  • interact 该命令用于保持交互模式

# Example

使用前Expect前,你需要了解你将要使用的命令的使用方法。

以及安装 Expect,可以在apt、yum等软件包市场或者官方网站下载。Expect (opens new window)

下面是我一个写上传 Spring Boot 打包后的 Jar 文件脚本

#!/bin/bash
#指定使用bash作为解析器

#JARNAME=打包后的Jar文件的正则匹配式
#USERNAME=用户名
#HOST=主机名
#PASSWORD=密码
#KEYPATH=密钥(看服务器登录方式)
#APPDIR=远端APP目录
#TARGETDIR=本机目标文件夹
#脚本需要使用到的变量

source ./private.sh
#该文件定义了以上的变量值

#运行 expect ,重定义输入和终止符,使得中间命令作为expect的输入
/usr/bin/expect << EOF
    set timeout -1
    #定义超时=无限
    spawn ssh ${USERNAME}@${HOST}
    #开启新进程
    expect "*password"
        send "${PASSWORD}"
    #期望得到提示输入密码,然后发送密码
    expect "*#"
        send "cd ${APPDIR}"
    expect "*#"
        send "./killAndDelete.sh"
        send "logout"
    #killAndDelete.sh 为远端清空当前项目进程和文件脚本
    expect eof
    #期望的到结束符
EOF 
#终止符

echo "success delete"

cd ${TARGETDIR}
FILENAME=$(ls | egrep "${JARNAME}" | sed -n 1p) #正则匹配并得到文件名
echo "find jar ${FILENAME}"

/usr/bin/expect << EOF
    set timeout -1
    spawn scp ${FILENAME} ${USERNAME}@${HOST}:${APPDIR}
    #使用scp上传新的文件
    expect "*password"
        send "${PASSWORD}"
    expect "ETA" {
        exp_continue;
    }
    #命令exp_continue用于重新开始该期望块,等待文件上传完成
EOF

echo "success upload"

/usr/bin/expect << EOF
    set timeout -1
    spawn ssh ${USERNAME}@${HOST}
    expect "*password"
        send "${PASSWORD}"
    expect "*#"
        send "cd ${APPDIR}/"
    expect "*#"
        send "./start.sh" # 远端开始脚本
    expect "*#" {
        sleep 10
        send "cat nohup.out"
        sleep 10
        send "cat nohup.out" #检测项目启动状况
        send "logout"
    }
    expect eof
EOF

echo "success start"

上述脚本调用了两个远端脚本,源代码与本文无关,不贴上了。

  • killAndDelete.sh 作用为关闭项目并删除原文件
  • start.sh 为启动新上传的文件

使用它们配合本机部署脚本,可以将打包后的文件一键自动替换并部署到远端服务器上。

#

expect 的更多语法请参见 man 手册。