随笔 - 12  文章 - 0  评论 - 0  阅读 - 10516 

一、Python pexpect 库的使用

在终端中许多命令都有与用户交互的场景,例如切换用户时需要手动输入密码,安装应用有时要输入默认配置等。这对 shell 自动化脚本十分不便。expect 命令的出现解决了上述问题。下面简单演示 shell 中使用 expect 命令自动输入密码切换用户并用切换后的用户执行命令的流程。

原版 shell 执行 expect 命令演示

在终端按以下步骤执行(其中 123 是 root 用户的密码),可以登录到 root 用户的终端。

user@host:~$ expect
expect1.1> set tiemout 5
5
expect1.2> spawn su
spawn su
3712
expect1.3> expect "Password" "密码"
Password: expect1.4> send "123\n"
expect1.5> interact

root@host:/home/user# 

这样就进入了 root 用户的终端。这时或许会有人说,写这么多,还不如直接执行 su 命令。事实上,真正的 expect 指令不会像这样直接在终端运行,而是作为脚本来运行。下面使用 Python 的 os 库中的 system 函数模拟在终端输入命令。以脚本的方式运行,感受 expect 的强大。

from os import system as shell_command

# expect 脚本如下
script = """#!/usr/bin/expect
set timeout 5
spawn su
expect {
"Password" {send "123\\\\r"}
"密码" {send "123\\\\r"}
}
send "whoami > whoami.txt\\\\r"
send "exit\\\\r"
expect eof
"""
# print(script)

# 先清理先前测试残留的文件
shell_command("rm -f whoami.txt")

# 用 echo 的方式创建 expect 脚本
shell_command("echo '" + script + "' > /tmp/shell_expect_su_script.sh")
shell_command("chmod +x /tmp/shell_expect_su_script.sh")
shell_command("/tmp/shell_expect_su_script.sh")
print("\ncat whoami.txt = ", end="")
shell_command("cat whoami.txt")

spawn su
Password: 
root@Master: /home/hadooproot@Master/home/hadoop# whoami > whoami.txt
root@Master: /home/hadooproot@Master/home/hadoop# exit
exit

cat whoami.txt = root





0

在上面的例子中,无需手动输入 root 用户的密码,即可登录进 root 用户的终端,并将自己的名称(root)写入文件 whoami.txt 中。由此看来,expect 命令的存在,使全自动化脚本成为了可能。

Python 自动化脚本 pexpect 库演示

在 Python 中,提供了 pexpect 库,可以十分方便地使用 Python 代码实现 expect 命令的功能。下面演示使用 pexpect 切换到 root 用户并在 text.txt 中写入一些数据,最后用 os 库的 system 函数执行 cat 命令读取 text.txt 文件内容验证执行结果。

import pexpect, os

# 先清理先前残留下的文件
os.system("rm -f text.txt")
os.system("ls -l | grep 'text.txt'")

process = pexpect.spawn("su")
process.timeout = 5
process.expect("Password")
process.sendline("123")
process.sendline("echo export PATH=/home/hadoop > text.txt")
process.sendline("EOF")
process.close()

os.system("ls -l text.txt")
os.system("cat text.txt")
-rw-r--r-- 1 root root 25 Mar 10 23:30 text.txt
export PATH=/home/hadoop





0

可见,使用 Python 代码可以更加方便地实现 expect 的功能。

expect 脚本讲解

现在,讲解一下上述例子中 expect 脚本中的内容。

#!/usr/bin/expect   # 这条语句告诉操作系统用来解释脚本的程序的位置

set timeout 5       # 设置超时时间,单位是秒。超过这个时长,就认为执行失败并退出。
                    # 例如在这里,如果密码 ‘123’ 是错误的,那么等待 5 秒后无法登录进去就会退出。
                    
spawn su            # spawn 是 expect 的内部指令,后面接要在 shell 执行的命令,
                    # 这样 expect 会开启一个新的进程来执行这个命令并监听它。
                    
expect {                    # expect 的中文是 ‘期待’ 的意思,顾名思义,expect 会期待出现指定的字符串。

"Password" {send "123\r"}   # 双引号(必须写双引号,不能是单引号)中是 expect 指令等待 spawn 生成的程序
                            # (这里是 su)出现的字符串。
                            #
                            # 这里当 su 命令执行后出现 “Password” 时,就发送 send 后面的字符串 "123\r"
                            # 给 su 命令。
                            #
                            # 注意:123 后面的 \r 不能少,它表示我们输入 123 后按下的回车键。


"密码" {send "123\r"}        # 与上面一样,只不过这里 expect 期待的是 “密码” 而不是 “Password”。
} 
send "whoami > whoami.txt\r"  # 此时不出意外的话已经进入 root 的终端了,这里直接发送终端命令即可执行,同样注意 \r 不能少。
send "exit\r"                 # 发送命令 exit 退出 root 的终端。

expect eof          # 结束整个 expect 命令

参考:

shell expect的简单用法

Linux expect 介绍和用法

python之pexpect模块

#!/bin/bash

posted on   ——light  阅读(1148)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示