[英]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中運行,可能是bash
或dash
。 (您的sh
實際上可能是在POSIX兼容模式下運行的其他Shell,但這沒有任何區別。)
bash
和dash
都具有內置的time
函數,但是sh
沒有,因此您獲得/usr/bin/time
,這是一個正常程序。 這帶來的最重要的區別是,內置time
不是作為具有自己獨立的stdout和stderr的子進程運行的。
另外, sh
, bash
和dash
都具有不同的重定向語法。
但是,您嘗試做的事情乍一看似乎是錯誤的,而您只是在控制台上很幸運,因為兩個錯誤正在消除。
您想擺脫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.