Shell 交互输入自动化

Shell 交互输入自动化,我们知道命令可以接受命令行参数。Linux也支持很多交互式应用程序,如passwdssh
我们可以创建自己的交互式shell脚本。对于普通用户而言,相较于记忆命令行参数及其正确的顺序,同一系列提示信息打交道要更容易。例如,一个备份用户工作成果的脚本看起来应该像这样:

$ backupWork.sh

如果你需要返回到同一交互式应用,实现交互式应用自动化能够节省大量的时间;如果你正在开发此类应用,这也可以避免你陷入重复输入的挫折感中。

Shell交互输入自动化

预备知识

任务自动化的第一步就是运行程序,然后注意需要执行什么操作。之前讲过的脚本命令可能会派上用场。

实战演练

观察交互式输入的顺序。参照上面的代码,我们可以将涉及的步骤描述如下:

notes[Return]docx[Return]

输入notes,按回车键,然后输入docx,再按回车键。这一系列操作可以被转换成下列字符串:

"notes\ndocx\n"

按下回车键时会发送\n。添加\n后,就生成了发送给stdin的字符串。
通过发送与用户输入等效的字符串,我们就可以实现在交互过程中自动发送输入。

工作原理

先写一个读取交互式输入的脚本,然后用这个脚本做自动化演示:

#!/bin/bash
# backup.sh
# 使用后缀备份文件。不备份以~开头的临时文件
read -p " What folder should be backed up: " folder
read -p " What type of files should be backed up: " suffix
find folder -name "*.suffix" -a ! -name '~*' -exec cp {} \
    BACKUP/LOGNAME/folder
echo "Backed up files fromfolder to BACKUP/LOGNAME/$folder"

按照下面的方法向脚本发送自动输入:

$ echo -e "notes\ndocx\n" | ./backup.sh
Backed up files from notes to /BackupDrive/MyName/notes

像这样的交互式脚本自动化能够在开发和调试过程中节省大量输入。另外还可以确保每次测试都相同,不会出现由于输入错误导致的bug假象。

我们用echo -e来生成输入序列。-e选项表明echo会解释转义序列。如果输入内容比较多,可以用单独的输入文件结合重定向操作符来提供输入:

$ echo -e "notes\ndocx\n" > input.data
$ cat input.data
notes
docx

你也可以选择手动构造输入文件,不使用echo命令:

$ ./interactive.sh < input.data

这种方法是从文件中导入交互式输入数据。

如果你是一名逆向工程师,那可能免不了要同缓冲区溢出攻击打交道。要实施攻击,我们需要将十六进制形式的shellcode(例如\xeb\x1a\x5e\x31\xc0\x88\x46)进行重定向。这些字符没法直接输入,因为键盘上并没有其对应的按键。因此,我们需要使用:

echo -e "\xeb\x1a\x5e\x31\xc0\x88\x46"

这条命令会将这串字节序列重定向到有缺陷的可执行文件中。

echo命令和重定向可以实现交互式输入的自动化。但这种技术存在问题,因为输入内容没有经过验证,我们认定目标应用总是以相同的顺序接收数据。但如果程序要求的输入顺序不同,或是对某些输入内容不做要求,那就要出岔子了。

expect程序能够执行复杂的交互操作并适应目标应用的变化。该程序在世界范围内被广泛用于控制硬件测试、验证软件构建、查询路由器统计信息等。

补充内容

expect是一个和shell类似的解释器。它基于TCL语言。我们将讨论如何使用spawnexpectsend命令实现简单的自动化。借助于TCL语言的强大功能,expect能够完成更为复杂的任务。你可以通过网站http://www.tcl.tk学到有关TCL语言的更多内容。

expect实现自动化

Linux发行版默认并不包含expect。你得用软件包管理器(apt-getyum)手动进行安装。
expect有3个主要命令,如下表所示:

命令 描述
spawn 运行新的目标应用
expect 关注目标应用发送的模式
send 向目标应用发送字符串

下面的例子会先执行备份脚本,然后查找模式*folder**file*,以此确定备份脚本是否要求输入目录名或文件名并作出相应的回应。如果重写备份脚本,要求先输入备份文件类型,后输入备份目录,这个自动化脚本依然能够应对。

#!/usr/bin/expect
#文件名: automate_expect.tcl
spawn ./backup .sh
expect {
  "*folder*" {
     send "notes\n"
     exp_continue
   }
  "*type*" {
     send "docx\n"
     exp_continue
  }
}

运行该脚本:

$ ./automate_expect.tcl

spawn命令的参数是需要自动化运行的应用程序及其参数。
expect命令接受一组模式以及匹配模式时要执行的操作。操作需要放入花括号中。
send命令是要发送的信息。和echo -n -e类似,send不会自动添加换行符,也能够理解转义字符。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程