简介
在shell工程开发的时候,为了减少和用户的交互,一般会采用expect免交互的方式,自动应答在部署过程中的停顿,使得部署过程对于用户友好。
本文演示了使用expect的用法.
关于类似的shell工程可以参考 05-06 周一 Shell工程目录划分和开发最佳实践
调用脚本-组织调用参数
yangfei@ubuntu:~/ci-deploy$ vim module/check_user_passwd.sh
#!/bin/bash
echo "验证配置文件中的所有用户名和密码是否匹配"
# 读取 JSON 文件并遍历 ci_repositories
jq -c '.repositories[]' "$config_file" | while IFS= read -r repository; do
# 从每个 repository 中提取 user、passwd、url 和 tags
user=$(echo "$repository" | jq -r '.user')
passwd=$(echo "$repository" | jq -r '.passwd')
echo "验证用户: $user passwd: $passwd"
../utils/verificate_password_local.sh "$user" "$passwd"
result=$?
echo "result=$result"
if [ $result -eq 0 ] ; then
echo "user $user password $passwd is correct"
continue
fi
echo "Please check user $user passwd: $passwd"
exit 127
done
上述代码演示了
- expect脚本的调用
- 基于退出码判断用户名密码是否正确
expect脚本验证用户密码并实现多个退出码verificate_password_local.sh
yangfei@ubuntu:~/ci-deploy$ cat utils/verificate_password_local.sh
#!/usr/bin/expect -f
# author: songquanheng
# date: 2024年4月24日16:17:43
# desc: 该脚本用于使用expect判断用户是否存在以及用户名密码是否匹配
# 设置超时时间,这里设置为10秒
set timeout 10
# 通过命令行参数传递用户名和密码
set username [lindex $argv 0]
set password [lindex $argv 1]
puts "username $username"
puts "password $password"
set status_code 42
# puts "username: $username"
# puts "password: $password"
# 启动交互式程序
spawn su - $username
expect {
"Password:" {
# 提供密码
send "$password\r"
}
-re "exist" {
puts "user $username does not exist"
exit 4
}
}
expect {
-re "Authentication failure" {
puts "Login failed. password wrong."
exit 1
}
-re "$username@" {
puts "Login success."
exit 0
}
timeout {
puts "Login failed. Connection timed out.";
exit 2
}
}
exit $status_code
yangfei@ubuntu:~/ci-deploy$
上述代码演示了如下的内容:
- 从位置参数中读取并设置到脚本变量
- spawn 开启会话
- expect子句
- 多个退出方式。
总结
自动应答是一个部署过程中必不可少的组件,还是非常有用的。