Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Apakah cara Python untuk menjalankan arahan secara tidak segerak dalam subproses tidak menyekat

Apakah cara Python untuk menjalankan arahan secara tidak segerak dalam subproses tidak menyekat

WBOY
WBOYke hadapan
2023-06-02 18:51:241407semak imbas

1. Apakah itu asyncio.subprocess.Process

Kami boleh melaksanakan arahan daripada asyncio. Perintah ini akan dilaksanakan dalam proses anak yang dibenarkan menggunakan I/O tanpa sekatan untuk operasi baca dan tulis.

Modul subproses dalam modul asyncio menyediakan kelas Proses yang mewakili subproses yang dijalankan oleh asyncio. Dalam program asyncio, ia menyediakan pemegang kepada proses kanak-kanak, membolehkan untuk melaksanakan operasi padanya, seperti menunggu dan menamatkan.

API sangat serupa dengan kelas berbilang pemprosesan.Proses dan mungkin lebih serupa dengan kelas subproses.Popen. Khususnya, ia berkongsi kaedah seperti wait(), communicate(), dan send_signal() dan sifat seperti stdin, stdout dan stderr dengan subprocess.Popen.

Sekarang kita tahu apa itu kelas asyncio.subprocess.Process, mari lihat cara menggunakannya dalam program asyncio kami.

Kami tidak akan menjana kejadian asyncio.subprocess.Process secara langsung. Sebaliknya, apabila menjalankan subproses dalam atur cara asyncio, contoh kelas dicipta secara automatik.

Terdapat dua cara untuk melaksanakan program luaran sebagai subproses dan mendapatkan contoh Proses, ia adalah:

  • asyncio.create_subprocess_exec() digunakan untuk menjalankan arahan secara langsung.

  • Gunakan fungsi asyncio.create_subprocess_shell() untuk menjalankan arahan menggunakan shell.

Mari kita lihat setiap contoh secara bergilir.

2. Cara menjalankan arahan secara langsung

Arahan ialah program yang dilaksanakan pada baris arahan (terminal atau command prompt). Ini adalah satu lagi program yang dijalankan secara langsung.

Contoh biasa pada Linux dan macOS mungkin:

  • ‘ls’ Senaraikan kandungan direktori

  • &lsquo ;cat’Laporkan kandungan fail

  • tarikh laporan "data"

  • ‘gema&rsquo laporkan rentetan

  • ‘tidur’ Tidur selama beberapa saat

Dengan menggunakan fungsi create_subprocess_exec(), kita boleh melaksanakan arahan dalam program asyncio.

Fungsi asyncio.create_subprocess_exec() menerima arahan dan melaksanakannya secara langsung.

Ini berguna kerana ia membenarkan perintah dilaksanakan dalam proses anak dan membenarkan coroutine asyncio membaca, menulis dan menunggu padanya.

Tidak seperti fungsi asyncio.create_subprocess_shell(), asyncio.create_subprocess_exec() tidak menggunakan shell untuk melaksanakan arahan.

Ini bermakna ciri yang disediakan oleh shell, seperti pembolehubah shell, skrip dan kad bebas, tidak tersedia semasa melaksanakan arahan.

Ini juga bermakna melaksanakan arahan mungkin lebih selamat kerana tiada peluang untuk suntikan cangkerang.

Sekarang kita tahu apa yang asyncio.create_subprocess_exec() lakukan, mari lihat cara menggunakannya.

2.1. Cara menggunakan Asyncio create_subprocess_exec()

Fungsi asyncio.create_subprocess_exec() akan melaksanakan perintah rentetan yang diberikan dalam subproses.

Ia mengembalikan objek asyncio.subprocess.Process yang mewakili subprocess.

Memandangkan fungsi create_subprocess_exec() ialah coroutine, kita perlu menunggunya. Ia kembali selepas subproses dimulakan, bukan apabila subproses selesai.

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

Apabila menggunakan fungsi create_subprocess_exec(), argumen kepada arahan mesti disediakan sebagai argumen seterusnya.

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

Kita boleh menunggu proses anak selesai dengan menunggu kaedah wait().

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

Kita boleh menghentikan proses anak secara langsung dengan memanggil kaedah terminate() atau kill(), yang akan menimbulkan isyarat dalam proses anak.

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

Input, output dan ralat standard akan dikendalikan melalui stdin, stderr dan stdout. Kita boleh membiarkan program asyncio mengendalikan input atau output proses anak.

Ini boleh dicapai dengan menentukan aliran input atau output dan menentukan pemalar untuk mengubah hala, seperti asyncio.subprocess.PIPE.

Sebagai contoh, kita boleh mengubah hala output arahan ke program asyncio:

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

Kemudian kita boleh membaca output program melalui kaedah communicate() melalui asyncio.subprocess. Contoh proses.

Kaedah ini adalah coroutine dan mesti menunggu. Ia digunakan untuk menghantar dan menerima data melalui subproses.

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

Kami juga boleh menghantar data kepada proses anak melalui kaedah communicate() dengan menetapkan parameter "input" dalam bait.

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

Di latar belakang, asyncio.subprocess.PIPE mengkonfigurasi subproses untuk menghala ke StreamReader atau StreamWriter untuk menghantar data ke atau daripada subproses, dan kaedah communicate() akan membaca daripada yang dikonfigurasikan Pemproses membaca atau menulis bait.

Kami boleh berinteraksi secara langsung dengan StreamReader atau StreamWriter melalui subproses melalui sifat stdin, stdout dan stderr.

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

Mari kita lihat beberapa contoh praktikal menggunakan fungsi create_subprocess_exec() , kini kita mempunyai pegangan tentang cara menggunakannya.

2.2. Contoh Asyncio create_subprocess_exec()

Kita boleh meneroka cara menjalankan arahan dalam subproses asyncio. Dalam contoh ini, kami akan melaksanakan perintah "gema" untuk melaporkan rentetan.

Arahan gema akan melaporkan rentetan yang dibekalkan terus pada output standard. Contoh lengkap disenaraikan di bawah.

Sila ambil perhatian bahawa contoh ini menganggap anda mempunyai akses kepada arahan "gema", saya tidak pasti sama ada ia akan berfungsi pada 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 执行命令。称为命令行解释器 (CLI),shell 是用来操作命令行界面的用户界面。它将代表用户解释和执行命令。

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

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

cat /etc/services | wc -l

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

Apakah cara Python untuk menjalankan arahan secara tidak segerak dalam subproses tidak menyekat

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(&#39;ls&#39;)

我们可以通过等待 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(&#39;ls&#39;, 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(&#39;ls&#39;, stdin=asyncio.subprocess.PIPE)
# send data to the subprocess
process.communicate(input=b&#39;Hello\n&#39;)

在后台,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(&#39;echo Hello World&#39;)
    # report the details of the subprocess
    print(f&#39;subprocess: {process}&#39;)
 
# 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

Atas ialah kandungan terperinci Apakah cara Python untuk menjalankan arahan secara tidak segerak dalam subproses tidak menyekat. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam