跳转至

20. 在非阻塞子进程中运行命令

20. Run Commands in Non-Blocking Subprocesses

我们可以从asyncio执行命令。

命令将在子进程中运行,我们可以使用非阻塞I/O对其进行读写。

让我们更仔细地看看。

We can execute commands from asyncio.

The command will run in a subprocess that we can write to and read from using non-blocking I/O.

Let’s take a closer look.

20.1 什么是 asyncio.subprocess.Process

20.1 What is asyncio.subprocess.Process

asyncio通过asyncio.subprocess.Process 类提供了对于运行子进程的支持和表示。

它提供了 asyncio 程序中子进程的句柄,允许对其执行操作,例如等待和终止它。

Process是一个高级包装过后的类,允许与子进程通信并监视其完成情况。

INTERACTING WITH SUBPROCESSES

该 API 与 multiprocessing.Process 类非常相似,也许与 subprocess.Popen 类更新相似。

具体来说,它与 subprocess.Popen 共享 wait()communicate()send_signal() 等方法以及 stdinstdoutstderr 等属性。

现在我们知道了 asyncio.subprocess.Process 类是什么,让我们看看如何在 asyncio 程序中使用它。

我们不直接创建 asyncio.subprocess.Process

相反,当在 asyncio 程序中执行子进程时,会为我们创建该类的实例。

包装由 create_subprocess_exec()create_subprocess_shell() 函数创建的操作系统进程的对象。

INTERACTING WITH SUBPROCESSES

有两种方法可以将外部程序作为子进程执行并获取 Process 实例,它们是:

  • asyncio.create_subprocess_exec() 用于直接运行命令。
  • asyncio.create_subprocess_shell() 用于通过 shell 运行命令。

让我们依次看一下每个例子。

The asyncio.subprocess.Process class provides a representation of a subprocess run by asyncio.

It provides a handle on a subprocess in asyncio programs, allowing actions to be performed on it, such as waiting and terminating it.

Process is a high-level wrapper that allows communicating with subprocesses and watching for their completion.

INTERACTING WITH SUBPROCESSES

The API is very similar to the multiprocessing.Process class and perhaps more so with the subprocess.Popen class.

Specifically, it shares methods such as wait(), communicate(), and send_signal() and attributes such as stdin, stdout, and stderr with the subprocess.Popen.

Now that we know what the asyncio.subprocess.Process class is, let’s look at how we might use it in our asyncio programs.

We do not create a asyncio.subprocess.Process directly.

Instead, an instance of the class is created for us when executing a subprocess in an asyncio program.

An object that wraps OS processes created by the create_subprocess_exec() and create_subprocess_shell() functions.

INTERACTING WITH SUBPROCESSES

There are two ways to execute an external program as a subprocess and acquire a Process instance, they are:

  • asyncio.create_subprocess_exec() for running commands directly.
  • asyncio.create_subprocess_shell() for running commands via the shell.

Let’s look at examples of each in turn.

20.2 如何直接运行命令

20.2 How to Run a Command Directly

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

Linux 和 macOS 上的常见示例可能是:

  • ‘ls‘ 列出目录的内容
  • ‘cat‘ 报告文件的内容
  • ‘date‘ 报告日期
  • ‘echo‘ 报告一个字符串
  • ‘sleep‘ 睡眠几秒钟

等等。

我们可以通过 create_subprocess_exec() 函数从 asyncio 程序执行命令。

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

这很有用,因为它允许在子进程中执行命令,并允许异步协程读取、写入和等待它。

因为所有 asyncio 子进程函数都是异步的,并且 asyncio 提供了许多工具来使用这些函数,所以很容易并行执行和监视多个子进程。

ASYNCIO SUBPROCESSES

asyncio.create_subprocess_shell() 函数不同,asyncio.create_subprocess_exec() 不会使用 shell 执行命令。

这意味着 shell 提供的功能(例如 shell 变量、脚本和通配符)在执行命令时不可用。

这也意味着执行命令可能更安全,因为没有机会进行shell注入

现在我们知道了 asyncio.create_subprocess_exec() 的作用,让我们看看如何使用它。

A command is a program executed on the command line (terminal or command prompt). It is another program that is run directly.

Common examples on Linux and macOS might be:

  • ‘ls‘ to list the contents of a directory
  • ‘cat‘ to report the content of a file
  • ‘date‘ to report the date
  • ‘echo‘ to report back a string
  • ‘sleep‘ to sleep for a number of seconds

And so on.

We can execute a command from an asyncio program via the create_subprocess_exec() function.

The asyncio.create_subprocess_exec() function takes a command and executes it directly.

This is helpful as it allows the command to be executed in a subprocess and for asyncio coroutines to read, write, and wait for it.

Because all asyncio subprocess functions are asynchronous and asyncio provides many tools to work with such functions, it is easy to execute and monitor multiple subprocesses in parallel.

— ASYNCIO SUBPROCESSES

Unlike the asyncio.create_subprocess_shell() function, the asyncio.create_subprocess_exec() will not execute the command using the shell.

This means that the capabilities provided by the shell, such as shell variables, scripting, and wildcards are not available when executing the command.

It also means that executing the command may be more secure as there is no opportunity for a shell injection.

Now that we know what asyncio.create_subprocess_exec() does, let’s look at how to use it.

20.2.1 如何使用 Asyncio 的 create_subprocess_exec()

20.2.1 How to Use Asyncio create_subprocess_exec()

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

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

Process是一个高级包装器,允许与子进程通信并监视其完成情况。

INTERACTING WITH SUBPROCESSES

create_subprocess_exec() 函数是一个协程,这意味着我们必须等待它。 它会在子进程启动后返回,而不是在子进程完成时返回。

例如:

...
# 在子进程中执行命令
process = await asyncio.create_subprocess_exec('ls')

正在执行的命令的参数必须作为 create_subprocess_exec() 函数的后续参数提供。

例如:

...
# 在子进程中执行带参数的命令
process = await asyncio.create_subprocess_exec('ls', '-l')

我们可以通过等待 wait() 方法来等待子进程完成。

例如:

...
# 等待子进程终止
await process.wait()

我们可以通过调用 terminate()kill() 方法直接停止子进程,这将在子进程中引发一个信号。

例如:

...
# 终止子进程
process.terminate()

命令的输入和输出将由 stdinstderrstdout 处理。

我们可以让 asyncio 程序处理子进程的输入或输出。

这可以通过指定输入或输出流并指定要重定向的常量来实现,例如 asyncio.subprocess.PIPE

例如,我们可以将命令的输出重定向到 asyncio 程序:

...
# 启动子进程并重定向输出
process = await asyncio.create_subprocess_exec('ls', stdout=asyncio.subprocess.PIPE)

然后我们可以通过asyncio.subprocess.Process实例通过communicate()方法读取程序的输出。

该方法是一个协程,必须等待。 它用于通过子进程发送和接收数据。

例如:

...
# 从子进程读取数据
line = process.communicate()

我们还可以通过 communicate() 方法通过设置 “input” 参数(以字节为单位)将数据发送到子进程。

例如:

...
# 启动子进程并重定向输入
process = await asyncio.create_subprocess_exec('ls', stdin=asyncio.subprocess.PIPE)
# 向子进程发送数据
process.communicate(input=b'Hello\n')

在背后, asyncio.subprocess.PIPE 将子进程配置为指向 StreamReaderStreamWriter 用于向子进程发送数据或从子进程发送数据,以及 communicate() 方法 将从配置的读取器读取或写入字节。

如果 PIPE 传递给 stdin 参数,则 Process.stdin 属性将指向 StreamWriter 实例。 如果 PIPE 传递给 stdoutstderr 参数,则 Process.stdoutProcess.stderr 属性将指向 StreamReader 实例。

ASYNCIO SUBPROCESSES

我们可以通过子进程通过 stdinstdoutstderr 属性直接与 StreamReaderStreamWriter 交互。

例如:

...
# 从子进程输出流中读取一行
line = await process.stdout.readline()

现在我们知道如何使用 create_subprocess_exec() 函数,让我们看一些有效的示例。

The asyncio.create_subprocess_exec() function will execute a given string command in a subprocess.

It returns a asyncio.subprocess.Process object that represents the subprocess.

Process is a high-level wrapper that allows communicating with subprocesses and watching for their completion.

INTERACTING WITH SUBPROCESSES

The create_subprocess_exec() function is a coroutine, which means we must await it. It will return once the subprocess has been started, not when the subprocess is finished.

For example:

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

Arguments to the command being executed must be provided as subsequent arguments to the create_subprocess_exec() function.

For example:

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

We can wait for the subprocess to finish by awaiting the wait() method.

For example:

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

We can stop the subprocess directly by calling the terminate() or kill() methods, which will raise a signal in the subprocess.

For example:

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

The input and output of the command will be handled by stdin, stderr, and stdout.

We can have the asyncio program handle the input or output for the subprocess.

This can be achieved by specifying the input or output stream and specifying a constant to redirect, such as asyncio.subprocess.PIPE.

For example, we can redirect the output of a command to the asyncio program:

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

We can then read the output of the program via the asyncio.subprocess.Process instance via the communicate() method.

This method is a coroutine and must be awaited. It is used to both send and receive data with the subprocess.

For example:

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

We can also send data to the subprocess via the communicate() method by setting the “input” argument in bytes.

For example:

...
# 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')

Behind the scenes the asyncio.subprocess.PIPE configures the subprocess to point to a StreamReader or StreamWriter for sending data to or from the subprocess, and the communicate() method will read or write bytes from the configured reader.

If PIPE is passed to stdin argument, the Process.stdin attribute will point to a StreamWriter instance. If PIPE is passed to stdout or stderr arguments, the Process.stdout and Process.stderr attributes will point to StreamReader instances.

ASYNCIO SUBPROCESSES

We can interact with the StreamReader or StreamWriter directly via the subprocess via the stdin, stdout, and stderr attributes.

For example:

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

Now that we know how to use the create_subprocess_exec() function, let’s look at some worked examples.

20.2.2 Asyncio 的 create_subprocess_exec() 的示例

20.2.2 Example of Asyncio create_subprocess_exec()

我们可以探索如何在 asyncio 的子进程中运行命令。

在此示例中,我们将执行 “echo” 命令来报告一个字符串。

echo 命令将直接在标准输出上报告提供的字符串。

下面列出了完整的示例。

注意,此示例假设您有权访问 “echo” 命令,我不确定它是否适用于 Windows。

# SuperFastPython.com
# 使用 asyncio 作为子进程执行命令的示例
import asyncio

# 主协程
async def main():
    # 开始在子进程中执行命令
    process = await asyncio.create_subprocess_exec('echo', 'Hello World')
    # 报告子流程的详细信息
    print(f'subprocess: {process}')

# 入口点
asyncio.run(main())

运行该示例首先创建 main() 协程,并将其作为 asyncio 程序的入口点执行。

main() 协程运行并调用 create_subprocess_exec() 函数来执行命令。

创建子进程时,main() 协程会挂起。 返回一个 Process 实例。

main() 协程恢复并报告子进程的详细信息。 main() 进程终止,并且 asyncio 程序终止。

echo 命令的输出在命令行上报告。

这突出显示了我们如何从 asyncio 程序执行命令。

Hello World
subprocess: <Process 50249>

We can explore how to run a command in a subprocess from asyncio.

In this example, we will execute the “echo” command to report back a string.

The echo command will report the provided string on standard output directly.

The complete example is listed below.

Note, this example assumes you have access to the “echo” command, I’m not sure it will work on 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())

Running the example first creates the main() coroutine and executes it as the entry point into the asyncio program.

The main() coroutine runs and calls the create_subprocess_exec() function to execute a command.

The main() coroutine suspends while the subprocess is created. A Process instance is returned.

The main() coroutine resumes and reports the details of the subprocess. The main() process terminates and the asyncio program terminates.

The output of the echo command is reported on the command line.

This highlights how we can execute a command from an asyncio program.

Hello World
subprocess: <Process 50249>

20.3 如何跟shell一起运行一个命令

How to Run a Command Via the Shell

我们可以使用shell执行命令。

shell 是命令行的用户界面,称为命令行解释器 (CLI)。

它将代表用户解释并执行命令。

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

例如,我们可以将一个命令的输出重定向为另一个命令的输入,例如将“/etc/services”文件的内容重定向到字数统计“wc”命令并统计行数:

cat /etc/services | wc -l

基于 Unix 的操作系统中的 shell 示例包括:

  • ‘sh’
  • ‘bash’
  • ‘zsh’
  • 等等。

在 Windows 上,shell 可能是 cmd.exe

请参阅这个很棒的命令行 shell 列表:

shell已经在运行,它被用来启动Python程序。

您无需执行任何特殊操作即可获取或访问 shell。

我们可以通过 create_subprocess_shell() 函数从 asyncio 程序执行命令。

asyncio.create_subprocess_shell() 函数接受一个命令并使用当前用户 shell 执行它。

这很有用,因为它不仅允许执行命令,还允许使用 shell 的功能,例如重定向、通配符等。

… 指定的命令将通过 shell 执行。 如果您使用 Python 主要是为了增强它在大多数系统 shell 上提供的控制流,并且仍然希望方便地访问其他 shell 功能(例如 shell 管道、文件名通配符、环境变量扩展以及将 ~ 扩展到用户主目录),那么这会很有用。

SUBPROCESS — SUBPROCESS MANAGEMENT

该命令将在执行 asyncio 程序的进程的子进程中执行。

重要的是,asyncio 程序能够与子进程异步交互,例如 通过协程。

因为所有 asyncio 子进程函数都是异步的,并且 asyncio 提供了许多工具来使用这些函数,所以很容易并行执行和监视多个子进程。

ASYNCIO SUBPROCESSES

通过 shell 而不是直接执行命令时可能存在安全考虑。

这是因为执行命令的请求和正在执行的命令之间至少存在一层间接和解释,从而允许可能的恶意注入。

重要的应用程序有责任确保所有空格和特殊字符都被正确引用,以避免 shell 注入漏洞。

ASYNCIO SUBPROCESSES

现在我们知道了 asyncio.create_subprocess_shell() 的作用,让我们看看如何使用它。

We can execute commands using the shell.

The shell is a user interface for the command line, called a command line interpreter (CLI).

It will interpret and execute commands on behalf of the user.

It also offers features such as a primitive programming language for scripting, wildcards, piping, shell variables (e.g. PATH), and more.

For example, we can redirect the output of one command as input to another command, such as the contents of the “/etc/services” file into the word count “wc” command and count the number of lines:

cat /etc/services | wc -l

Examples of shells in the Unix based operating systems include:

  • ‘sh’
  • ‘bash’
  • ‘zsh’
  • And so on.

On Windows, the shell is probably cmd.exe.

See this great list of command line shells:

The shell is already running, it was used to start the Python program.

You don’t need to do anything special to get or have access to the shell.

We can execute a command from an asyncio program via the create_subprocess_shell() function.

The asyncio.create_subprocess_shell() function takes a command and executes it using the current user shell.

This is helpful as it not only allows the command to be executed, but allows the capabilities of the shell to be used, such as redirection, wildcards and more.

… the specified command will be executed through the shell. This can be useful if you are using Python primarily for the enhanced control flow it offers over most system shells and still want convenient access to other shell features such as shell pipes, filename wildcards, environment variable expansion, and expansion of ~ to a user’s home directory.

SUBPROCESS — SUBPROCESS MANAGEMENT

The command will be executed in a subprocess of the process executing the asyncio program.

Importantly, the asyncio program is able to interact with the subprocess asynchronously, e.g. via coroutines.

Because all asyncio subprocess functions are asynchronous and asyncio provides many tools to work with such functions, it is easy to execute and monitor multiple subprocesses in parallel.

— ASYNCIO SUBPROCESSES

There can be security considerations when executing a command via the shell instead of directly.

This is because there is at least one level of indirection and interpretation between the request to execute the command and the command being executed, allowing possible malicious injection.

Important It is the application’s responsibility to ensure that all whitespace and special characters are quoted appropriately to avoid shell injection vulnerabilities.

— ASYNCIO SUBPROCESSES

Now that we know what asyncio.create_subprocess_shell() does, let’s look at how to use it.

20.3.1 如何使用 Asyncio 的 create_subprocess_shell()

20.3.1 How to Use Asyncio create_subprocess_shell()

asyncio.create_subprocess_shell() 函数将通过当前 shell 执行给定的字符串命令。

它返回一个表示进程的 asyncio.subprocess.Process 对象。

它与我们在上一节中看到的 create_subprocess_shell() 函数非常相似。 尽管如此,我们将回顾如何使用该函数并通过 Process 实例与流程交互(如果您直接跳到本节)。

create_subprocess_shell() 函数是一个协程,这意味着我们必须等待它。 它会在子进程启动后返回,而不是在子进程完成时返回。

例如:

...
# 启动一个子进程
process = await asyncio.create_subprocess_shell('ls')

我们可以通过等待 wait() 方法来等待子进程完成。

例如:

...
# 等待子进程终止
await process.wait()

我们可以通过调用 terminate()kill() 方法直接停止子进程,这将在子进程中引发一个信号。

命令的输入和输出将由 shell 处理,例如 标准输入标准错误标准输出

我们可以让 asyncio 程序处理子进程的输入或输出。

这可以通过指定输入或输出流并指定要重定向的常量来实现,例如 asyncio.subprocess.PIPE

例如,我们可以将命令的输出重定向到 asyncio 程序:

...
# 启动子进程并重定向输出
process = await asyncio.create_subprocess_shell('ls', stdout=asyncio.subprocess.PIPE)

然后我们可以通过asyncio.subprocess.Process实例通过communicate()方法读取程序的输出。

该方法是一个协程,必须等待。 它用于通过子进程发送和接收数据。

例如:

...
# 从子进程读取数据
line = process.communicate()

我们还可以通过以字节为单位设置“input”参数,通过 communicate() 方法将数据发送到子进程。

例如:

...
# 启动子进程并重定向输入
process = await asyncio.create_subprocess_shell('ls', stdin=asyncio.subprocess.PIPE)
# 向子进程发送数据
process.communicate(input=b'Hello\n')

在背后, asyncio.subprocess.PIPE 将子进程配置为指向 StreamReaderStreamWriter 用于向子进程发送数据或从子进程发送数据,以及 communicate() 方法 将从配置的读取器读取或写入字节。

如果 PIPE 传递给 stdin 参数,则 Process.stdin 属性将指向 StreamWriter 实例。 如果 PIPE 传递给 stdout 或 stderr 参数,则 Process.stdout 和 Process.stderr 属性将指向 StreamReader 实例。

ASYNCIO SUBPROCESSES

我们可以通过子进程的 stdinstdoutstderr 属性直接与 StreamReaderStreamWriter 交互。

例如:

...
# 从子进程输出流中读取一行
line = await process.stdout.readline()

现在我们知道如何使用 create_subprocess_shell() 函数,让我们看一些有效的示例。

The asyncio.create_subprocess_shell() function will execute a given string command via the current shell.

It returns a asyncio.subprocess.Process object that represents the process.

It is very similar to the create_subprocess_shell() function we saw in a previous section. Nevertheless, we will review how to use the function and interact with the process via the Process instance (in case you skipped straight to this section).

The create_subprocess_shell() function is a coroutine, which means we must await it. It will return once the subprocess has been started, not when the subprocess is finished.

For example:

...
# start a subprocess
process = await asyncio.create_subprocess_shell('ls')
We can wait for the subprocess to finish by awaiting the **wait()** method.

For example:

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

We can stop the subprocess directly by calling the terminate() or kill() methods, which will raise a signal in the subprocess.

The input and output of the command will be handled by the shell, e.g. stdin, stderr, and stdout.

We can have the asyncio program handle the input or output for the subprocess.

This can be achieved by specifying the input or output stream and specifying a constant to redirect, such as asyncio.subprocess.PIPE.

For example, we can redirect the output of a command to the asyncio program:

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

We can then read the output of the program via the asyncio.subprocess.Process instance via the communicate() method.

This method is a coroutine and must be awaited. It is used to both send and receive data with the subprocess.

For example:

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

We can also send data to the subprocess via the communicate() method by setting the “input” argument in bytes.

For example:

...
# 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')

Behind the scenes the asyncio.subprocess.PIPE configures the subprocess to point to a StreamReader or StreamWriter for sending data to or from the subprocess, and the communicate() method will read or write bytes from the configured reader.

If PIPE is passed to stdin argument, the Process.stdin attribute will point to a StreamWriter instance. If PIPE is passed to stdout or stderr arguments, the Process.stdout and Process.stderr attributes will point to StreamReader instances.

ASYNCIO SUBPROCESSES

We can interact with the StreamReader or StreamWriter directly via the subprocess via the stdin, stdout, and stderr attributes.

For example:

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

Now that we know how to use the create_subprocess_shell() function, let’s look at some worked examples.

20.3.2 Asyncio 的 create_subprocess_shell() 的示例

20.3.2 Example of Asyncio create_subprocess_shell()

我们可以探索如何使用 shell 从 asyncio 的子进程中运行命令。

在此示例中,我们将执行 “echo” 命令来报告一个字符串。

echo 命令将直接在标准输出上报告提供的字符串。

下面列出了完整的示例。

请注意,此示例假设您有权访问“echo”命令,我不确定它是否适用于 Windows。

# SuperFastPython.com
# 使用 asyncio 作为子进程执行 shell 命令的示例
import asyncio

# 主协程
async def main():
    # 开始在子进程中执行 shell 命令
    process = await asyncio.create_subprocess_shell('echo Hello World')
    # 报告子流程的详细信息
    print(f'subprocess: {process}')

# 入口点
asyncio.run(main())

运行该示例首先创建 main() 协程并将其作为 asyncio 程序的入口点执行。

main() 协程运行并调用 create_subprocess_shell() 函数来执行命令。

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

main() 协程恢复并报告子流程的详细信息。 main() 进程终止,asyncio 程序终止。

echo 命令的输出在命令行上报告。

这突出显示了我们如何使用 asyncio 程序中的 shell 执行命令。

subprocess: <Process 43916>
Hello World

We can explore how to run a command in a subprocess from asyncio using the shell.

In this example, we will execute the “echo” command to report back a string.

The echo command will report the provided string on standard output directly.

The complete example is listed below.

Note, this example assumes you have access to the “echo” command, I’m not sure it will work on 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())

Running the example first creates the main() coroutine and executes it as the entry point into the asyncio program.

The main() coroutine runs and calls the create_subprocess_shell() function to execute a command.

The main() coroutine suspends while the subprocess is created. A Process instance is returned.

The main() coroutine resumes and reports the details of the subprocess. The main() process terminates and the asyncio program terminates.

The output of the echo command is reported on the command line.

This highlights how we can execute a command using the shell from an asyncio program.

subprocess: <Process 43916>
Hello World

最后更新: 2024年9月4日
创建日期: 2024年9月4日