一、问题
因为我把Mysql和Redis都是安装在了docker中(我本机是Linux系统,然后本机中安装了docker),每次开机都是先启动docker,然后输入密码,很麻烦
。
因为root权限是最高的,咱们不能拿root直接使用,不然操作失误之后,造成的损失可想而知(例如:一不小心用root执行了一个:\rm -r /)。
然后你可能:
但是
面对这种让你输入密码的情况,真的很烦
每次启动都是输入密码:
每次停止也是输入密码:
就研究了一下,有什么办法可以自动输入密码,交换式自动输入密码的方法,本文就是来说明这个的。
二、有请expect闪亮登场
(一)自我介绍:
使用
man expect
查看说明书
expect是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信
INTRODUCTION Expect is a program that "talks" to other interactive programs according to a script. Fol‐ lowing the script, Expect knows what can be expected from a program and what the correct response should be. An interpreted language provides branching and high-level control struc‐ tures to direct the dialogue. In addition, the user can take control and interact directly when desired, afterward returning control to the script. Expectk is a mixture of Expect and Tk. It behaves just like Expect and Tk's wish. Expect can also be used directly in C or C++ (that is, without Tcl). See libexpect(3). The name "Expect" comes from the idea of send/expect sequences popularized by uucp, kermit and other modem control programs. However unlike uucp, Expect is generalized so that it can be run as a user-level command with any program and task in mind. Expect can actually talk to several programs at the same time.
(二)expect自动交互流程
spawn启动指定进程--->expect获取指定关键字--->send向指定程序发送指定字符--->执行完成退出.
(三)expect常用命令解释
spawn
: 交互程序开始后面跟命令或者指定程序
expect
: 获取匹配信息匹配成功则执行expect后面的程序动作
send exp_send
: 用于发送指定的字符串信息
exp_continue
: 在expect中多次匹配就需要用到
send_user
: 用来打印输出 相当于shell中的echo
exit
: 退出expect脚本
eof
: expect执行结束 退出
set
:定义变量
puts
:输出变量
set timeout
: 设置超时时间
(四)实战脚本训练
创建一个新的脚本文件:
truedei@truedei:~$ truedei@truedei:~$ truedei@truedei:~$ vim sd
输入:
注意,第一行很重要,通常我们的脚本里第一行是#!/bin/bash,而这里是你机器上expect程序的路径,说明这段脚本是由expect来解释执行的,而不是由bash解释执行,所以代码的语法和shell脚本也是不一样的。
其中set是设置变量,spawn是执行的命令。
#!/usr/bin/expect #设置超时时间 set timeout 30 #执行需要执行的命令 spawn sudo docker start mysql57 #设置超时时间 set timeout 1000 #发送密码 send "1\r" #结束退出程序 expect eof
给脚本设置可执行权限:
truedei@truedei:~$ truedei@truedei:~$ chmod 777 sd truedei@truedei:~$ truedei@truedei:~$ cat sd #!/usr/bin/expect set timeout 30 #执行需要执行的命令 spawn sudo docker start mysql57 set timeout 1000 #发送密码 send "1\r" expect eof truedei@truedei:~$ truedei@truedei:~$ ./sd spawn sudo docker start mysql57 1 [sudo] truedei 的密码: mysql57 truedei@truedei:~$
可以看到已经执行了:
truedei@truedei:~$ sudo docker ps [sudo] truedei 的密码: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0a122a08125f mysql:5.7.29 "docker-entrypoint.s…" 5 weeks ago Up 3 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp mysql57 truedei@truedei:~$ truedei@truedei:~$
使用另一种办法,使用代码块的方式:
现在把命令,修改成停止的;
其实expect提供的是和终端的一种交互机制,输入密码只是其中一种应用形式,只要是在终端阻塞需要输入时,都可以通过expect脚本完成自动输入,比如前面脚本里配置了两种交互场景,一种是终端提示"password:"时输入密码;还要一种是提示你输入yes或者no;
因为我是中文的提示符,所以提示的是
密码
,所以我捕捉密码
.
truedei@truedei:~$ cat sd #!/usr/bin/expect set timeout 30 #执行需要执行的命令 spawn sudo docker stop mysql57 expect { "*密码*" { send "1\r" } } expect eof truedei@truedei:~$
执行:
可以看到已经停止了,大多数都是采用这种代码块形式来写的
truedei@truedei:~$ ./sd spawn sudo docker stop mysql57 [sudo] truedei 的密码: mysql57 truedei@truedei:~$ truedei@truedei:~$ truedei@truedei:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES truedei@truedei:~$ truedei@truedei:~$
三、升级脚本
(一)启动脚本:
truedei@truedei:~$ truedei@truedei:~$ cat startDockerAll #!/usr/bin/expect set timeout 30 #设置密码 set password 1 #执行需要执行的命令 spawn sudo docker start mysql57 expect { "*密码*" { send "$password\r" } } spawn sudo docker start redis expect { "*密码*" { send "$password\r" } } expect eof truedei@truedei:~$ truedei@truedei:~$
(二)停止脚本
truedei@truedei:~$ truedei@truedei:~$ cat stopDockerAll #!/usr/bin/expect set timeout 30 #设置密码 set password 1 #执行需要执行的命令 spawn sudo docker stop mysql57 expect { "*密码*" { send "$password\r" } } spawn sudo docker stop redis expect { "*密码*" { send "$password\r" } } expect eof truedei@truedei:~$ truedei@truedei:~$
四、成果
测试启动
truedei@truedei:~$ truedei@truedei:~$ ./startDockerAll spawn sudo docker start mysql57 [sudo] truedei 的密码:spawn sudo docker start redis [sudo] truedei 的密码: redis truedei@truedei:~$ truedei@truedei:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 85cb7d83a2ff redis "docker-entrypoint.s…" 24 hours ago Up 4 seconds 0.0.0.0:6379->6379/tcp redis 0a122a08125f mysql:5.7.29 "docker-entrypoint.s…" 5 weeks ago Up 4 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp mysql57 truedei@truedei:~$ truedei@truedei:~$
测试停止
truedei@truedei:~$ ./stopDockerAll spawn sudo docker stop mysql57 [sudo] truedei 的密码:spawn sudo docker stop redis [sudo] truedei 的密码: redis truedei@truedei:~$ truedei@truedei:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES truedei@truedei:~$
感谢下文博主的删库跑路的图片:
https://www.sohu.com/a/255496462_100021113
感谢这位大神的相关介绍:
https://www.cnblogs.com/saneri/p/10819348.html
五、小郑有话说
如果对你有帮助,可以分享给你身边的朋友。或者给俺点个大大的赞和大大的评论,点赞和评论就是给我最大的支持,感谢。
水平有限,难免会有疏漏或者书写不合理的地方,欢迎交流讨论。