您好,登錄后才能下訂單哦!
今天小編給大家分享一下Python異步在非阻塞子進(jìn)程中運行命令的方法是什么的相關(guān)知識點,內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
我們可以從 asyncio 執(zhí)行命令。該命令將在我們可以使用非阻塞 I/O 寫入和讀取的子進(jìn)程中運行。
asyncio.subprocess.Process 類提供了由 asyncio 運行的子進(jìn)程的表示。它在 asyncio 程序中提供子進(jìn)程的句柄,允許對其執(zhí)行操作,例如等待和終止它。
該 API 與 multiprocessing.Process 類非常相似,可能與 subprocess.Popen 類更相似。具體來說,它與 subprocess.Popen 共享 wait()、communicate() 和 send_signal() 等方法以及 stdin、stdout 和 stderr 等屬性。
現(xiàn)在我們知道了 asyncio.subprocess.Process 類是什么,讓我們看看如何在我們的 asyncio 程序中使用它。
我們不直接創(chuàng)建 asyncio.subprocess.Process。相反,在 asyncio 程序中執(zhí)行子進(jìn)程時,會為我們創(chuàng)建一個類的實例。
有兩種方法可以將外部程序作為子流程執(zhí)行并獲取 Process 實例,它們是:
asyncio.create_subprocess_exec() 用于直接運行命令。
asyncio.create_subprocess_shell() 用于通過 shell 運行命令。
讓我們依次看一下每個示例。
命令是在命令行(終端或命令提示符)上執(zhí)行的程序。這是另一個直接運行的程序。
Linux 和 macOS 上的常見示例可能是:
‘ls’ 列出目錄的內(nèi)容
‘cat’報告文件的內(nèi)容
“data”報告日期
‘echo’ 報告一個字符串
‘sleep’ 睡眠幾秒鐘
我們可以通過 create_subprocess_exec() 函數(shù)從 asyncio 程序執(zhí)行命令。
asyncio.create_subprocess_exec() 函數(shù)接受一個命令并直接執(zhí)行它。
這很有用,因為它允許命令在子進(jìn)程中執(zhí)行,并允許 asyncio 協(xié)程讀取、寫入和等待它。
與 asyncio.create_subprocess_shell() 函數(shù)不同,asyncio.create_subprocess_exec() 不會使用 shell 執(zhí)行命令。
這意味著 shell 提供的功能,例如 shell 變量、腳本和通配符,在執(zhí)行命令時不可用。
這也意味著執(zhí)行命令可能更安全,因為沒有機(jī)會進(jìn)行 shell 注入。
現(xiàn)在我們知道了 asyncio.create_subprocess_exec() 的作用,讓我們看看如何使用它。
asyncio.create_subprocess_exec() 函數(shù)將在子進(jìn)程中執(zhí)行給定的字符串命令。
它返回一個代表子進(jìn)程的 asyncio.subprocess.Process 對象。
create_subprocess_exec() 函數(shù)是一個協(xié)程,這意味著我們必須等待它。它會在子流程啟動后返回,而不是在子流程完成時返回。
... # execute a command in a subprocess process = await asyncio.create_subprocess_exec('ls')
正在執(zhí)行的命令的參數(shù)必須作為后續(xù)參數(shù)提供給 create_subprocess_exec() 函數(shù)。
... # execute a command with arguments in a subprocess process = await asyncio.create_subprocess_exec('ls', '-l')
我們可以通過等待 wait() 方法來等待子進(jìn)程完成。
... # wait for the subprocess to terminate await process.wait()
我們可以通過調(diào)用 terminate() 或 kill() 方法直接停止子進(jìn)程,這將在子進(jìn)程中引發(fā)一個信號。
... # terminate the subprocess process.terminate()
命令的輸入和輸出將由 stdin、stderr 和 stdout 處理。我們可以讓 asyncio 程序處理子進(jìn)程的輸入或輸出。
這可以通過指定輸入或輸出流并指定要重定向的常量來實現(xiàn),例如 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() 方法讀取程序的輸出。
此方法是協(xié)程,必須等待。它用于通過子流程發(fā)送和接收數(shù)據(jù)。
... # read data from the subprocess line = process.communicate()
我們還可以通過以字節(jié)為單位設(shè)置“input”參數(shù),通過 communicate() 方法將數(shù)據(jù)發(fā)送到子進(jìn)程。
... # 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 將子進(jìn)程配置為指向 StreamReader 或 StreamWriter,用于向子進(jìn)程發(fā)送數(shù)據(jù)或從子進(jìn)程發(fā)送數(shù)據(jù),并且 communicate() 方法將從配置的讀取器讀取或?qū)懭胱止?jié)。
我們可以通過子進(jìn)程通過 stdin、stdout 和 stderr 屬性直接與 StreamReader 或 StreamWriter 交互。
... # read a line from the subprocess output stream line = await process.stdout.readline()
現(xiàn)在我們知道如何使用 create_subprocess_exec() 函數(shù),讓我們看一些工作示例。
我們可以探索如何在 asyncio 的子進(jìn)程中運行命令。在這個例子中,我們將執(zhí)行“echo”命令來報告一個字符串。
echo 命令將直接在標(biāo)準(zhǔn)輸出上報告提供的字符串。下面列出了完整的示例。
請注意,此示例假設(shè)您可以訪問“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())
運行示例首先創(chuàng)建 main() 協(xié)程并將其作為 asyncio 程序的入口點執(zhí)行。
main() 協(xié)程運行并調(diào)用 create_subprocess_exec() 函數(shù)來執(zhí)行命令。
main() 協(xié)程在創(chuàng)建子進(jìn)程時掛起。返回一個 Process 實例。
main() 協(xié)程恢復(fù)并報告子進(jìn)程的詳細(xì)信息。 main() 進(jìn)程終止,asyncio 程序終止。
echo 命令的輸出在命令行上報告。這突出了我們?nèi)绾螐?asyncio 程序執(zhí)行命令。
Hello World subprocess: <Process 50249>
我們可以使用 shell 執(zhí)行命令。shell 是命令行的用戶界面,稱為命令行解釋器 (CLI)。它將代表用戶解釋和執(zhí)行命令。
它還提供諸如用于腳本、通配符、管道、shell 變量(例如 PATH)等的原始編程語言等功能。
例如,我們可以將一條命令的輸出重定向為另一條命令的輸入,比如將“/etc/services”文件的內(nèi)容重定向到word count命令“wc”中,統(tǒng)計行數(shù):
cat /etc/services | wc -l
基于 Unix 的操作系統(tǒng)中的 shell 示例包括:
shell 已經(jīng)在運行,它被用來啟動 Python 程序。您無需執(zhí)行任何特殊操作即可獲取或訪問 shell。
我們可以通過 create_subprocess_shell() 函數(shù)從 asyncio 程序執(zhí)行命令。
asyncio.create_subprocess_shell() 函數(shù)接受一個命令并使用當(dāng)前用戶 shell 執(zhí)行它。
這很有用,因為它不僅允許執(zhí)行命令,還允許使用 shell 的功能,例如重定向、通配符等。
該命令將在執(zhí)行 asyncio 程序的進(jìn)程的子進(jìn)程中執(zhí)行。重要的是,asyncio 程序能夠與子進(jìn)程異步交互,例如通過協(xié)程。
通過 shell 而不是直接執(zhí)行命令時,可能會有安全考慮。
這是因為請求執(zhí)行命令和正在執(zhí)行的命令之間至少存在一層間接和解釋,允許可能的惡意注入。
現(xiàn)在我們知道了 asyncio.create_subprocess_shell() 的作用,讓我們看看如何使用它。
asyncio.create_subprocess_shell() 函數(shù)將通過當(dāng)前 shell 執(zhí)行給定的字符串命令。
它返回一個表示進(jìn)程的 asyncio.subprocess.Process 對象。
它與我們在上一節(jié)中看到的 create_subprocess_shell() 函數(shù)非常相似。不過,我們將回顧如何使用該函數(shù)以及如何通過 Process 實例與流程交互(以防您直接跳到本節(jié))。
create_subprocess_shell() 函數(shù)是一個協(xié)程,這意味著我們必須等待它。它會在子流程啟動后返回,而不是在子流程完成時返回。
... # start a subprocess process = await asyncio.create_subprocess_shell('ls')
我們可以通過等待 wait() 方法來等待子進(jìn)程完成。
... # wait for the subprocess to terminate await process.wait()
我們可以通過調(diào)用 terminate() 或 kill() 方法直接停止子進(jìn)程,這將在子進(jìn)程中引發(fā)一個信號。
命令的輸入和輸出將由 shell 處理,例如標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)錯誤和標(biāo)準(zhǔn)輸出。
我們可以讓 asyncio 程序處理子進(jìn)程的輸入或輸出。
這可以通過指定輸入或輸出流并指定要重定向的常量來實現(xiàn),例如 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() 方法讀取程序的輸出。
此方法是協(xié)程,必須等待。它用于通過子流程發(fā)送和接收數(shù)據(jù)。
... # read data from the subprocess line = process.communicate()
我們還可以通過以字節(jié)為單位設(shè)置“input”參數(shù),通過 communicate() 方法將數(shù)據(jù)發(fā)送到子進(jìn)程。
... # 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 將子進(jìn)程配置為指向 StreamReader 或 StreamWriter,用于向子進(jìn)程發(fā)送數(shù)據(jù)或從子進(jìn)程發(fā)送數(shù)據(jù),并且 communicate() 方法將從配置的讀取器讀取或?qū)懭胱止?jié)。
我們可以通過子進(jìn)程通過 stdin、stdout 和 stderr 屬性直接與 StreamReader 或 StreamWriter 交互。
... # read a line from the subprocess output stream line = await process.stdout.readline()
現(xiàn)在我們知道如何使用 create_subprocess_shell() 函數(shù),讓我們看一些工作示例。
我們可以探索如何使用 shell 在 asyncio 的子進(jìn)程中運行命令。在這個例子中,我們將執(zhí)行“echo”命令來報告一個字符串。
echo 命令將直接在標(biāo)準(zhǔn)輸出上報告提供的字符串。下面列出了完整的示例。
請注意,此示例假設(shè)您可以訪問“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())
運行示例首先創(chuàng)建 main() 協(xié)程并將其作為 asyncio 程序的入口點執(zhí)行。main() 協(xié)程運行并調(diào)用 create_subprocess_shell() 函數(shù)來執(zhí)行命令。
main() 協(xié)程運行并調(diào)用 create_subprocess_shell() 函數(shù)來執(zhí)行命令。main() 協(xié)程恢復(fù)并報告子進(jìn)程的詳細(xì)信息。 main() 進(jìn)程終止,asyncio 程序終止。
echo 命令的輸出在命令行上報告。這突出顯示了我們?nèi)绾问褂?shell 從 asyncio 程序執(zhí)行命令。
subprocess: <Process 43916> Hello World
以上就是“Python異步在非阻塞子進(jìn)程中運行命令的方法是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。