Python Pexpect模块
我们都知道桌面操作系统及其功能和工作原理。我们听说过的一些最著名的操作系统是Windows、Linux、macOS和ChromeOS。其中,ChromeOS也是一种基于Linux的桌面操作系统,增加了Linux和基于Linux的操作系统的流行度。Linux是程序员和开发人员中非常流行的操作系统,因为它具有增强的安全功能。但与此同时,它不太受普通人的欢迎,而这一趋势背后的最大原因是操作和使用基于Linux的桌面操作系统所使用的复杂命令。
现在,谈到Linux,它是UNIX-like操作系统家族中的一个桌面操作系统,由Linus Torvalds于1991年9月17日首次发布。除了其安全功能之外,Linux的另一个吸引人之处是它是一个基于FOSS(Free Open-Source Software)模型的开源和免费许可软件。与Windows和许多其他桌面操作系统不同,Linux是完全免费的,人们可以下载其最新版本和上百个发行版。Linux为开发人员提供的其他功能包括更快的解释器和编译器、进行大量定制化的选项、较少的操作系统复杂性等。但是,如果我们没有Linux操作系统但仍然想使用Linux命令怎么办。可能有很多原因导致这样做,包括我们可能想熟悉Linux命令等。也许并非所有的编程语言,但Python为我们提供了这个选项,可以在Windows或任何其他操作系统上运行Linux命令。为此,Python有pexpect模块,通过使用其函数,它为我们提供了使用Python程序自动化Linux命令的选项。因此,我们将学习有关Python的pexpect模块的所有内容,并了解如何使用它通过Python程序运行Linux命令。
Python的Pexpect模块简介
Pexpect是一个Python包,用于执行许多功能,包括通过Python程序自动化Linux命令、生成子进程并自动控制它们等。Pexpect模块是Python的一个非常丰富的模块,带有许多函数来执行许多不同的任务。Pexpect模块作为一个生成的子进程,并根据我们使用Python程序定义的预期模式来执行多个功能。
以下是我们可以使用Python的pexpect模块执行的一些有用功能:
- FTP密码,
- ssh,
- Telnet,
- 自动化Linux命令等
Python Pexpect模块的安装
Pexpect不是Python的内置包(它不随Python安装而安装),所以如果系统中没有该模块,我们必须安装该模块。我们首先要确保pexpect模块是否已经安装在系统中,因为没有该模块,我们将无法执行实现。如果Pexpect模块已经没有安装在我们的系统中,我们可以通过多种方法安装该模块,在所有可能的安装方法中,使用pip安装程序安装pexpect模块是最简单和最容易的。因此,我们将在本节中使用pip安装程序在我们的系统中安装该模块,在这种方法中,我们将使用以下pip安装程序命令:
pip install pexpect
我们需要在命令提示符终端中输入上述命令,并在输入命令后按下回车键,这样pip安装程序就会开始在我们的系统中安装此模块。一旦安装过程开始,它将花费一些时间来成功安装该模块到我们的系统中,我们需要等待此过程完成。
如我们所见,成功安装的消息显示在我们的屏幕上,这意味着pexpect模块现在已经成功安装在我们的系统中。现在,我们可以继续Pexpect模块的实施部分,并将其导入到示例程序中以了解其工作原理。
使用Pexpect模块自动化Linux命令
在这部分中,我们将通过在Python程序中导入Pexpect模块来自动化Linux命令。我们在pexpect模块中有三种方法,可以通过Python程序自动执行Linux命令。
以下是使用pexpect模块自动化Linux命令的三种方法:
- 使用run()方法
- 使用spawn类方法
- 使用sendline()方法
我们将通过在示例程序中使用这些方法来了解上述所有三种方法的实现。我们将为每种方法使用一个单独的示例程序并通过它来自动执行Linux命令。
注意:上面列出的所有pexpect模块方法仅适用于基于UNIX的操作系统,并且没有一个适用于Windows。因此,如果我们在Windows操作系统中运行这些方法或示例程序,它将在输出中显示错误。因此,如果我们想在Windows操作系统中运行这些程序,首先必须为基于UNIX的操作系统设置一个虚拟环境。
方法1:使用run()方法
在pexpect模块中,我们有一个run()函数,我们可以使用它来运行和执行命令。我们可以使用pexpect.run()方法来执行Linux命令,只需将其作为参数提供给函数,然后可以将执行的结果返回给输出。run()函数可以用作os.system方法的替代,后者用于执行Linux命令。
run()方法的语法:
使用pexpect模块的run()方法执行Linux命令的语法如下:
>> pexpect.run(Linux command)
如上所示的语法中,我们在run()方法中提供了一个Linux命令作为参数。当我们运行程序时,run()方法将执行提供的Linux命令,并在输出中显示结果。
让我们通过以下示例程序来了解执行Linux命令的run()方法的实现。
示例1: 看一下下面的Python程序,我们执行了一个Linux命令:
# Importing pexpect module
import pexpect as px
# Using run method with Linux command
executionResult = px.run('echo Welcome to JavaTpoint!')
# Showing result in the output
print("The result after executing Linux commands through run method:")
print(executionResult)
输出:
The result after executing Linux commands through run method:
Welcome to JavaTpoint!
如我们所见,Linux命令成功执行,并且结果在输出中打印出来。
说明:
在程序中将pexpect模块作为px导入后,我们使用了run()方法来执行一个示例Linux命令,即打印’Welcome to JavaTpoint!’,并将其存储在一个初始化的变量executionResult中。最后,我们使用print语句将执行结果打印到输出中。
方法2:使用Spawn类方法
在这种方法中,我们将使用一个Spawn类来帮助我们自动化程序中给出的Linux命令。 Spawn类是我们可以在执行过程中启动新的子进程并通过子类对其进行控制的主要接口。我们在Spawn类中给出的字符串参数可以被需要执行的shell命令(在适当时)替换。
Spawn类的语法:
>> pexpect.spawn('Linux Command')
正如我们所看到的,我们在spawn类中提供了一个Linux命令作为参数,并且可以用要执行的shell命令替换它。
在使用spawn类方法时,我们可以使用expect()函数,这也是spawn类的一个重要方法。expect()方法等待由我们为spawn类定义的子类进行处理,以便返回给定的字符串输入之一。当我们运行程序时,我们在spawn类函数中指定的模式将与子类中定义的输入字符串匹配,并将匹配的字符串返回到输出中。在子类中使用的expect()将返回spawn类的输入模式在输出中匹配的字符串位置。
expect()函数的语法:
我们必须像下面给出的语法一样,在spawn方法的子类中使用expect()函数:
>> childClassObject.expect(inputPatterns, searchwindowsize = -1, async_ = false)
参数: 如上所述的expect()函数的语法,该函数接受以下三个参数:
- inputPatterns: 这些是要与我们在spawn类中定义的模式匹配的输入字符串模式,这是必须提供的函数中的参数。
- searchwindowsize: 这是一个可选的窗口大小,定义搜索窗口的大小。该函数中此参数的默认值为-1。
- async_: 这也是expect()函数的可选参数,此参数的输入值为“True”和“False”。该函数中此参数的默认值为False。当创建非阻塞应用程序时,我们可以将此值设置为“True”。
expect()函数中使用的超时值来引发返回值将是pexpect.TIMEOUT。我们可以使用expect()函数的searchwindow选项设置类的maxread值。
让我们通过以下示例程序通过子类理解使用expect()函数的spawn类方法的实现。
示例2: 请看下面的Python程序,我们在spawn类中定义了匹配的输入模式:
# Importing pexpect module
import pexpect as px
# Starting a child process with spawn class
childProcess = px.spawn("echo JavaTpoint")
# Matching the defined pattern with input strings of expect() function
processResult = childProcessing.expect(["Welcome", "To", "JavaTpoint", "Hello"])
# Returning matched string index result in the output
print("The defined pattern in the spawn class is matched at the index number:", processResult, "from the input strings given in expect function")
输出:
The defined pattern in the spawn class is matched at the index number: 2 from the input strings given in expect function
正如我们所看到的,在执行spawn类之后,匹配定义模式的输入字符串的索引编号将打印在输出中。这就是我们如何将在expect()函数中给定的输入字符串与spawn类中定义的模式进行匹配。由于索引编号从0开始,所以第三个位置的输入字符串的地方打印索引号2。
解释:
我们在程序中导入pexpect模块,并使用spawn类启动一个子进程。在启动子进程时,我们定义了一个模式’JavaTpoint’,该模式将与给定的输入字符串进行匹配。之后,我们使用expect()函数,在该函数中定义了多个输入字符串。将与定义的模式匹配的字符串的索引编号将作为结果存储在初始化的变量中。最后,我们使用初始化的变量在打印语句中打印结果。
方法3:使用sendline方法
在使用spawn类启动子进程之后,我们将使用sendline()函数。sendline()方法将覆盖为子进程定义的模式字符串。sendline方法还用于返回由我们定义的模式字符串消耗的字节数,但在此部分中,我们只将使用此方法来匹配输入字符串中的模式。当我们为子进程写入字符串时,此方法用于自动化Linux命令。
sendline方法的语法:
以下是使用pexpect模块的sendline方法编写子进程匹配模式的语法:
>> childProcess.sendline("pattern")
如我们所见,sendline函数只接受一个参数,即子进程的模式。
通过以下示例程序,我们可以理解sendline方法的实现和应用:
示例3: 查看以下Python程序,我们在其中使用sendline()函数来编写与子进程匹配的模式:
# Importing pexpect module
import pexpect as px
# Starting a child process with spawn class
childProcess = px.spawn("JavaTpoint")
# Definite pattern for the child process
childProcess.sendline("Welcome")
# Matching defined pattern with input strings
processResult = childProcessing.expect(["Welcome", "To", "JavaTpoint", "Hello"])
# Returning matched string index result in the output
print("The defined pattern for the child process by the sendline method is matched at the index number: ", processResult)
输出:
The defined pattern for the child process by the sendline method is matched at the index number: 0
如我们所见,在执行之后,输出中打印了从expect()函数中匹配与sendline方法定义的模式相匹配的输入字符串的索引号。这就是我们如何使用sendline方法定义和匹配子进程的模式。
解释:
启动子进程后,我们使用了sendline()函数,在其中定义了子进程的模式。然后,我们将定义的模式与输入字符串在expect()函数中给出的输入字符串进行匹配。最后,我们打印了与子进程的定义模式相匹配的输入字符串的索引号。