[英]Invoking C compiler using Python subprocess command
我正在嘗試使用Python編譯一個C程序,並希望使用“<”運算符進行輸入,但它沒有按預期工作。 如果我編譯C程序並通過提供輸入來運行它,它可以工作; 例如
./a.out <inp.txt works
但同樣地,如果我嘗試使用Python腳本執行此操作,那么它並沒有像預期的那樣完成。 例如:
import subprocess
subprocess.call(["gcc","a.c","-o","x"])
subprocess.call(["./x"])
和
import subprocess
subprocess.call(["gcc","a.c","-o","x"])
subprocess.call(["./x","<inp.txt"])
兩個腳本都要求終端輸入。 但我認為在第二個腳本中它應該從文件中讀取。 為什么兩個程序都一樣?
補充@Jonathan Leffler和@ alastair 的有用答案:
假設您控制了傳遞給shell執行的字符串,我認為使用shell是為了方便。 [1]
subprocess.call()
有一個可選的Boolean shell
參數,它會將命令傳遞給shell ,啟用I / O重定向,引用環境變量,......:
subprocess.call("./x <inp.txt", shell = True)
請注意整個命令行如何作為單個字符串而不是參數數組傳遞 。
[1] 在下列情況下避免使用shell:
如果您擔心shell環境缺乏可預測性 (如@alastair所示):
subprocess.call
與shell = True
總是創建的非交互式非登錄實例/bin/sh
-請注意,這不是所使用的用戶的默認外殼。 sh
不讀取非交互式非登錄shell的初始化文件 (既不是系統范圍的也不是用戶特定的)。
sh
是bash
偽裝, bash
時的調用將這樣的行為sh
。 shell = True
subprocess.call
創建的每個shell實例都是它自己的世界,它的環境既不受以前的shell實例的影響,也不影響以后的實例。 env
參數為shell 提供自己的環境 ; 但請注意, 您必須在該事件中提供整個環境 ,如果需要,可能包括USER
和HOME
等變量; 簡單的例子,明確定義$PATH
: subprocess.call('echo $PATH', shell = True, \\ env = { 'PATH': '/sbin:/bin:/usr/bin' })
shell為進程執行I / O重定向。 根據您的說法, subprocess
模塊不會像這樣進行I / O重定向。 要演示,請運行:
subprocess.call(["sh","-c", "./x <inp.txt"])
它運行shell並應重定向I / O. 使用您的代碼,您的程序./x
將被賦予一個它忽略的參數<inp.txt
。
注意:對subprocess.call
的替代調用純粹是出於診斷目的,而不是推薦的解決方案。 推薦的解決方案包括閱讀(Python 2) 子流程模塊文檔(或Python 3文檔),以了解如何使用模塊進行重定向。
import subprocess
i_file = open("inp.txt")
subprocess.call("./x", stdin=i_file)
i_file.close()
如果您的腳本即將退出,那么您不必擔心浪費的文件描述符,您可以將其壓縮為:
import subprocess
subprocess.call("./x", stdin=open("inp.txt"))
默認情況下, subprocess
模塊不會將參數傳遞給shell。 為什么? 因為通過shell運行命令是危險的 ; 除非它們被正確引用和轉義(這很復雜),否則通常可以說服執行此類操作的程序運行不需要的和意外的shell命令。
無論如何,使用shell都是錯誤的。 如果要從特定文件獲取輸入,可以使用subprocess.Popen
,將stdin
參數設置為文件inp.txt
(可以通過調用fileno()
獲取文件描述符Python文件對象)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.