如何使用Python运行bash脚本?

如果您使用Linux,那么您肯定会喜欢shell命令。

如果您使用Python,那么您可能已经尝试自动化一些东西。这是节省时间的一种方式。您可能还有一些bash脚本来自动化一些东西。

Python比bash更方便编写脚本。与bash脚本相比,管理Python脚本更容易。一旦bash脚本变得越来越复杂,您会发现很难维护它。

但是如果您已经有了想要使用Python运行的bash脚本怎么办?

有没有办法在Python中执行bash命令和脚本?

是的,Python有一个内置模块叫做subprocess,用于在Python脚本中执行命令和脚本。让我们详细看看如何在Python脚本中执行bash命令和脚本。

执行Bash命令

如您可能已经看到的,模块subprocess用于执行bash命令和脚本。它提供了不同的方法和类。

主要有一个方法和一个类要了解的是subprocess模块。它们是runPopen。这两个帮助我们在Python脚本中执行bash命令。让我们逐个看看。

subprocess.run()

方法subprocess.run()将以列表形式接收一个字符串作为位置参数。这是强制性的,因为它包含了bash命令和其参数。列表中的第一项是命令名称,其余项是命令的参数。

让我们来看一个快速示例。

import subprocess
subprocess.run(["ls"])

上面的脚本会列出当前工作目录中的所有项目。上面的脚本中没有命令的参数。我们只提供了bash命令。我们可以为ls命令提供其他参数,如-l-a-la等。

让我们来看一个带有命令参数的快速示例。

import subprocess
subprocess.run(["ls", "-la"])

上面的命令显示包括隐藏文件和权限在内的所有文件。我们提供了la参数,该参数显示了文件和目录的额外信息以及隐藏文件。

在编写命令时,我们可能会犯一些错误。根据错误会引发异常。如果希望捕获并稍后使用它们怎么办?是的,我们可以使用关键字参数stderr来实现。

让我们来看一个示例。

import subprocess
result = subprocess.run(["cat", "sample.txt"], stderr=subprocess.PIPE, text=True)
print(result.stderr)

确保您的工作目录中没有名为sample.txt的文件。关键字参数stderr的值为PIPE,它将错误以对象的形式返回。我们可以使用相同的名称稍后访问它。关键字参数text告诉输出应该是一个字符串。

类似地,我们可以使用stdout关键字参数来捕获命令的输出。

import subprocess
result = subprocess.run(["echo", "Hello, World!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(result.stdout)

subprocess.run() – input

您可以使用input关键字参数为命令提供输入。我们将以字符串格式提供输入。因此,我们需要将关键字参数text设置为True。默认情况下,它以字节形式接收输入。

让我们看一个示例。

import subprocess
subprocess.run(["python3", "add.py"], text=True, input="2 3")

在上面的程序中,Python脚本add.py 将接受两个数字作为输入。我们使用input 关键字参数将输入传递给Python脚本。

subprocess.Popen()

subprocess.Popen() 比方法subprocess.run()更高级。它提供了更多的选项来执行命令。我们将创建一个subprocess.Popen() 的实例,并将其用于诸如了解命令执行状态、获取输出、提供输入等的各种操作。

subprocess.Popen()有几个需要了解的方法。让我们逐个查看它们以及代码示例。

wait

它用于等待命令执行完成。在wait方法之后编写的Python脚本的下一行不会执行,直到前一个命令执行完成。让我们看一个例子。

“`python
import subprocess
process = subprocess.Popen([“ls”, “-la”])
print(“Completed!”)
“`

观察输出。你会发现打印出了Completed! 的消息,而命令执行之前。我们可以使用wait方法避免这种情况。让我们等待命令的完成。

“`python
import subprocess
process = subprocess.Popen([“ls”, “-la”])
process.wait()

print(“Completed!”)
“`

如果你看到上面代码的输出,你会意识到wait确实起作用。在命令执行完成后,打印语句才会执行。

communicate

方法communicate用于获取输出、错误和给命令输入。它返回一个包含输出和错误的元组。让我们看一个例子。

“`python
import subprocess
process = subprocess.Popen([“echo”, “Hello, World!”], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
result = process.communicate()
print(result)
“`

subprocess.Popen() – input

我们不能直接将输入传递给类Popen。我们需要使用关键字参数stdin 将输入传递给命令。类Popen的实例将为我们提供一个stdin对象。它有一个称为write的方法,用于向命令输入数据。

如前所述,默认情况下,它将以类似字节的对象的形式接收输入。因此,在创建Popen的实例时,请不要忘记将关键字参数text 设置为True

让我们看一个例子。

“`python
import subprocess
process = subprocess.Popen([“python3”, “add.py”], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
process.stdin.write(“2 3”)
process.stdin.close()
print(process.stdout.read())
“`

poll

方法poll用于检查命令是否执行完成。如果命令仍在执行,此方法将返回None。让我们看一个例子。

“`python
import subprocess
process = subprocess.Popen([‘ping', ‘-c 5', ‘yaoweibin.com'], stdout=subprocess.PIPE, text=True)
while True:
output = process.stdout.readline()
if output:
print(output.strip())
result = process.poll()
if result is not None:
break
“`

在上面的代码中,我们使用了带有5个请求的ping命令。有一个无限循环,它在命令执行完成之前进行迭代。我们使用poll方法来检查命令执行的状态。如果poll方法返回的代码不是None,则表示执行完成。然后退出无限循环。

执行Bash脚本

我们已经看到了两种执行命令的方式。现在,让我们看看如何在Python脚本中执行Bash脚本。

subprocess 有一个叫做call的方法。这个方法用于执行Bash脚本。该方法返回Bash脚本的退出代码。Bash脚本的默认退出代码为0。让我们看一个例子。

创建一个名为practice.sh的Bash脚本,内容如下。

#!/bin/bash

echo "Hello, World!"
exit 1

现在,编写一个Python脚本来执行上述Bash脚本。

import subprocess
exit_code = subprocess.call('./practice.sh')
print(exit_code)

当你运行上述Python脚本时,你将得到以下输出。

Hello, World!
1

结论

我们已经看到了如何在Python中执行Bash命令和脚本。你可以使用它们来更高效地自动化工作。

Happy Coding 👨‍💻

类似文章