搞定shell脚本expect自动化交互输入密码等就是这么简单

一、问题

因为我把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

五、小郑有话说

如果对你有帮助,可以分享给你身边的朋友。或者给俺点个大大的赞和大大的评论,点赞和评论就是给我最大的支持,感谢。
水平有限,难免会有疏漏或者书写不合理的地方,欢迎交流讨论。
作者:TrueDei
作者唯一博客CSDN:https://truedei.blog.csdn.net/
转载说明:如需转载请注明原地址和作者名。

如果喜欢我的文章,还没看够可以关注我,我会用心写好每一篇文章。

手撕代码八百里 CSDN认证博客专家 Linux 分布式 Java
原名:TrueDei,现:手撕代码八百里

不荒废现在,不畏惧未来!我认为把知识给别人讲会,讲明白,自己才彻底明白。努力把文章写好,写明白每一篇文章,分享给更多人。
相关推荐
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:白松林 返回首页
实付 49.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值