动动发财的小手,点个赞吧!

咱们能够从 asyncio 履行指令。该指令将在咱们能够运用非阻塞 I/O 写入和读取的子进程中运转。

1. 什么是 asyncio.subprocess.Process

asyncio.subprocess.Process 类提供了由 asyncio 运转的子进程的表明。它在 asyncio 程序中提供子进程的句柄,答应对其履行操作,例如等候和中止它。

该 API 与 multiprocessing.Process 类非常类似,或许与 subprocess.Popen 类更类似。具体来说,它与 subprocess.Popen 共享 wait()、communicate() 和 send_signal() 等办法以及 stdin、stdout 和 stderr 等属性。

现在咱们知道了 asyncio.subprocess.Process 类是什么,让咱们看看如安在咱们的 asyncio 程序中运用它。

咱们不直接创立 asyncio.subprocess.Process。相反,在 asyncio 程序中履行子进程时,会为咱们创立一个类的实例。

有两种办法能够将外部程序作为子流程履行并获取 Process 实例,它们是:

  • asyncio.create_subprocess_exec() 用于直接运转指令。
  • asyncio.create_subprocess_shell() 用于经过 shell 运转指令。

让咱们依次看一下每个示例。

2. 怎么直接运转指令

指令是在指令行(终端或指令提示符)上履行的程序。这是另一个直接运转的程序。

Linux 和 macOS 上的常见示例或许是:

  • ‘ls’ 列出目录的内容
  • ‘cat’陈述文件的内容
  • “data”陈述日期
  • ‘echo’ 陈述一个字符串
  • ‘sleep’ 睡觉几秒钟

咱们能够经过 create_subprocess_exec() 函数从 asyncio 程序履行指令。

asyncio.create_subprocess_exec() 函数接受一个指令并直接履行它。

这很有用,由于它答应指令在子进程中履行,并答应 asyncio 协程读取、写入和等候它。

与 asyncio.create_subprocess_shell() 函数不同,asyncio.create_subprocess_exec() 不会运用 shell 履行指令。

这意味着 shell 提供的功用,例如 shell 变量脚本和通配符,在履行指令时不可用。

这也意味着履行指令或许更安全,由于没有机会进行 shell 注入。

现在咱们知道了 asyncio.create_subprocess_exec() 的效果,让咱们看看怎么运用它。

2.1. 怎么运用 Asyncio create_subprocess_exec()

asyncio.create_subprocess_exec() 函数将在子进程中履行给定的字符串指令。

它回来一个代表子进程的 asyncio.subprocess.Process 对象。

create_subprocess_exec() 函数是一个协程,这意味着咱们有必要等候它。它会在子流程发动后回来,而不是在子流程完结时回来。

...
# execute a command in a subprocess
process = await asyncio.create_subprocess_exec('ls')

正在履行的指令的参数有必要作为后续参数提供给 create_subprocess_exec() 函数。

...
# execute a command with arguments in a subprocess
process = await asyncio.create_subprocess_exec('ls', '-l')

咱们能够经过等候 wait() 办法来等候子进程完结。

...
# wait for the subprocess to terminate
await process.wait()

咱们能够经过调用 terminate() 或 kill() 办法直接中止子进程,这将在子进程中引发一个信号。

...
# terminate the subprocess
process.terminate()

指令的输入和输出将由 stdin、stderr 和 stdout 处理。咱们能够让 asyncio 程序处理子进程的输入或输出。

这能够经过指定输入或输出流并指定要重定向的常量来实现,例如 asyncio.subprocess.PIPE。

例如,咱们能够将指令的输出重定向到 asyncio 程序:

...
# start a subprocess and redirect output
process = await asyncio.create_subprocess_exec('ls', stdout=asyncio.subprocess.PIPE)

然后咱们能够经过 asyncio.subprocess.Process 实例经过 communicate() 办法读取程序的输出。

此办法是协程,有必要等候。它用于经过子流程发送和接纳数据。

...
# read data from the subprocess
line = process.communicate()

咱们还能够经过以字节为单位设置“input”参数,经过 communicate() 办法将数据发送到子进程。

...
# start a subprocess and redirect input
process = await asyncio.create_subprocess_exec('ls', stdin=asyncio.subprocess.PIPE)
# send data to the subprocess
process.communicate(input=b'Hello\n')

在后台,asyncio.subprocess.PIPE 将子进程装备为指向 StreamReader 或 StreamWriter,用于向子进程发送数据或从子进程发送数据,而且 communicate() 办法将从装备的读取器读取或写入字节。

咱们能够经过子进程经过 stdin、stdout 和 stderr 属性直接与 StreamReader 或 StreamWriter 交互。

...
# read a line from the subprocess output stream
line = await process.stdout.readline()

现在咱们知道怎么运用 create_subprocess_exec() 函数,让咱们看一些工作示例。

2.2. Asyncio create_subprocess_exec() 示例

咱们能够探究如安在 asyncio 的子进程中运转指令。在这个比如中,咱们将履行“echo”指令来陈述一个字符串。

echo 指令将直接在规范输出上陈述提供的字符串。下面列出了完好的示例。

请注意,此示例假设您能够拜访“echo”指令,我不确定它是否适用于 Windows。

# SuperFastPython.com
# example of executing a command as a subprocess with asyncio
import asyncio
# main coroutine
async def main():
    # start executing a command in a subprocess
    process = await asyncio.create_subprocess_exec('echo', 'Hello World')
    # report the details of the subprocess
    print(f'subprocess: {process}')
# entry point
asyncio.run(main())

运转示例首要创立 main() 协程并将其作为 asyncio 程序的进口点履行。

main() 协程运转并调用 create_subprocess_exec() 函数来履行指令。

main() 协程在创立子进程时挂起。回来一个 Process 实例。

main() 协程康复并陈述子进程的详细信息。 main() 进程中止,asyncio 程序中止。

echo 指令的输出在指令行上陈述。这杰出了咱们怎么从 asyncio 程序履行指令。

Hello World
subprocess: <Process 50249>

3. 怎么经过 Shell 运转指令

咱们能够运用 shell 履行指令。shell 是指令行的用户界面,称为指令行解说器 (CLI)。它将代表用户解说和履行指令。

它还提供比如用于脚本、通配符、管道、shell 变量(例如 PATH)等的原始编程语言等功用。

例如,咱们能够将一条指令的输出重定向为另一条指令的输入,比如将“/etc/services”文件的内容重定向到word count指令“wc”中,统计行数:

cat /etc/services | wc -l

根据 Unix 的操作系统中的 shell 示例包括:

Python 异步: 在非阻塞子进程中运行命令(19)

shell 已经在运转,它被用来发动 Python 程序。您无需履行任何特别操作即可获取或拜访 shell。

咱们能够经过 create_subprocess_shell() 函数从 asyncio 程序履行指令。

asyncio.create_subprocess_shell() 函数接受一个指令并运用当时用户 shell 履行它。

这很有用,由于它不只答应履行指令,还答应运用 shell 的功用,例如重定向、通配符等。

该指令将在履行 asyncio 程序的进程的子进程中履行。重要的是,asyncio 程序能够与子进程异步交互,例如经过协程。

经过 shell 而不是直接履行指令时,或许会有安全考虑。

这是由于恳求履行指令和正在履行的指令之间至少存在一层直接和解说,答应或许的恶意注入。

现在咱们知道了 asyncio.create_subprocess_shell() 的效果,让咱们看看怎么运用它。

3.1. 怎么运用 Asyncio create_subprocess_shell()

asyncio.create_subprocess_shell() 函数将经过当时 shell 履行给定的字符串指令。

它回来一个表明进程的 asyncio.subprocess.Process 对象。

它与咱们在上一节中看到的 create_subprocess_shell() 函数非常类似。不过,咱们将回忆怎么运用该函数以及怎么经过 Process 实例与流程交互(以防您直接跳到本节)。

create_subprocess_shell() 函数是一个协程,这意味着咱们有必要等候它。它会在子流程发动后回来,而不是在子流程完结时回来。

...
# start a subprocess
process = await asyncio.create_subprocess_shell('ls')

咱们能够经过等候 wait() 办法来等候子进程完结。

...
# wait for the subprocess to terminate
await process.wait()

咱们能够经过调用 terminate() 或 kill() 办法直接中止子进程,这将在子进程中引发一个信号。

指令的输入和输出将由 shell 处理,例如规范输入、规范过错和规范输出。

咱们能够让 asyncio 程序处理子进程的输入或输出。

这能够经过指定输入或输出流并指定要重定向的常量来实现,例如 asyncio.subprocess.PIPE。

例如,咱们能够将指令的输出重定向到 asyncio 程序:

...
# start a subprocess and redirect output
process = await asyncio.create_subprocess_shell('ls', stdout=asyncio.subprocess.PIPE)

然后咱们能够经过 asyncio.subprocess.Process 实例经过 communicate() 办法读取程序的输出。

此办法是协程,有必要等候。它用于经过子流程发送和接纳数据。

...
# read data from the subprocess
line = process.communicate()

咱们还能够经过以字节为单位设置“input”参数,经过 communicate() 办法将数据发送到子进程。

...
# start a subprocess and redirect input
process = await asyncio.create_subprocess_shell('ls', stdin=asyncio.subprocess.PIPE)
# send data to the subprocess
process.communicate(input=b'Hello\n')

在后台,asyncio.subprocess.PIPE 将子进程装备为指向 StreamReader 或 StreamWriter,用于向子进程发送数据或从子进程发送数据,而且 communicate() 办法将从装备的读取器读取或写入字节。

咱们能够经过子进程经过 stdin、stdout 和 stderr 属性直接与 StreamReader 或 StreamWriter 交互。

...
# read a line from the subprocess output stream
line = await process.stdout.readline()

现在咱们知道怎么运用 create_subprocess_shell() 函数,让咱们看一些工作示例。

3.2. Asyncio create_subprocess_shell() 示例

咱们能够探究怎么运用 shell 在 asyncio 的子进程中运转指令。在这个比如中,咱们将履行“echo”指令来陈述一个字符串。

echo 指令将直接在规范输出上陈述提供的字符串。下面列出了完好的示例。

请注意,此示例假设您能够拜访“echo”指令,我不确定它是否适用于 Windows。

# SuperFastPython.com
# example of executing a shell command as a subprocess with asyncio
import asyncio
# main coroutine
async def main():
    # start executing a shell command in a subprocess
    process = await asyncio.create_subprocess_shell('echo Hello World')
    # report the details of the subprocess
    print(f'subprocess: {process}')
# entry point
asyncio.run(main())

运转示例首要创立 main() 协程并将其作为 asyncio 程序的进口点履行。main() 协程运转并调用 create_subprocess_shell() 函数来履行指令。

main() 协程运转并调用 create_subprocess_shell() 函数来履行指令。main() 协程康复并陈述子进程的详细信息。 main() 进程中止,asyncio 程序中止。

echo 指令的输出在指令行上陈述。这杰出显示了咱们怎么运用 shell 从 asyncio 程序履行指令。

subprocess: <Process 43916>
Hello World

本文由mdnice多渠道发布