簡體   English   中英

Python,subprocess.check_call()和管道重定向

[英]Python, subprocess.check_call() and pipes redirection

為什么執行此命令時會得到文件列表?

subprocess.check_call("time ls &>/dev/null", shell=True)

如果我貼上

time ls &>/dev/null

進入控制台,我將獲得計時。 操作系統是Linux Ubuntu。

在類似debian的系統上,默認shell是dash ,而不是bash Dash不支持&>快捷方式。 要僅獲取子流程返回代碼,請嘗試:

subprocess.check_call("time ls >/dev/null 2>&1", shell=True)

要獲取子流程的返回碼和時間信息,而不是目錄列表,請使用:

subprocess.check_call("time ls >/dev/null", shell=True)

當然,減去子流程返回代碼,這與在dash命令提示符下看到的行為相同。

Python版本在sh下運行,但控制台版本在您的默認Shell中運行,可能是bashdash (您的sh實際上可能是在POSIX兼容模式下運行的其他Shell,但這沒有任何區別。)

bashdash都具有內置的time函數,但是sh沒有,因此您獲得/usr/bin/time ,這是一個正常程序。 這帶來的最重要的區別是,內置time不是作為具有自己獨立的stdout和stderr的子進程運行的。

另外, shbashdash都具有不同的重定向語法。


但是,您嘗試做的事情乍一看似乎是錯誤的,而您只是在控制台上很幸運,因為兩個錯誤正在消除。

您想擺脫ls的標准輸出,但要保留time標准,但這不是您要的。 您正在嘗試同時重定向stdout和stderr:這是在實際支持它的任何shell上>&意思。

那么,為什么還需要time呢? (a)您的默認外殼程序不支持>& ,或(b)您使用內置程序而不是程序,並且您沒有重定向外殼程序本身的stderr,或者(c)兩者都以上。


如果您真的想在Python中執行完全相同的操作,並且以完全相同的方式消除完全相同的錯誤,則可以手動運行默認的Shell,而不是使用shell=True 根據工作的原因,可能是這樣的:

subprocess.check_call([os.environ['SHELL'], '-c', 'time ls &> /dev/null'])

或這個:

subprocess.check_call('{} -c time ls &> /dev/null'.format(os.environ(SHELL), shell=True)

但實際上,您為什么要這樣做呢? 如果要重定向標准輸出而不是標准錯誤,請寫:

subprocess.check_call('time ls > /dev/null', shell=True)

或者,更好的是,為什么還要使用外殼?

subprocess.check_call(['time', 'ls'], stdout=subprocess.devnull)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM