[英]Python: Executing a shell command
我需要這樣做:
paste file1 file2 file3 > result
我的python腳本中包含以下內容:
from subprocess import call
// other code here.
// Here is how I call the shell command
call ["paste", "file1", "file2", "file3", ">", "result"])
不幸的是我得到這個錯誤:
paste: >: No such file or directory.
任何幫助都會很棒!
如果您明智地決定不使用Shell,則需要自己實現重定向。
https://docs.python.org/2/library/subprocess.html上的文檔警告您不要使用管道-但是,您不需要:
import subprocess
with open('result', 'w') as out:
subprocess.call(["paste", "file1", "file2", "file3"], stdout=out)
應該很好。
有兩種方法。
使用shell=True
:
call("paste file1 file2 file3 >result", shell=True)
重定向>
是Shell功能。 因此,您只能在使用shell時使用它: shell=True
。
保持shell=False
並使用python執行重定向:
with open('results', 'w') as f: subprocess.call(["paste", "file1", "file2", "file3"], stdout=f)
通常首選第二個,因為它避免了外殼的變化。
當不使用外殼程序時, >
只是命令行上的另一個字符。 因此,請考慮錯誤消息:
paste: >: No such file or directory.
這表明paste
已接收到>
作為參數,並試圖使用該名稱打開文件。 沒有這樣的文件。 因此消息。
作為shell命令行,可以使用該名稱創建文件:
touch '>'
如果存在這樣的文件,則subprocess
使用shell=False
調用時, paste
會使用該文件作為輸入。
如果您不介意在代碼庫中添加其他依賴項,則可以考慮安裝sh Python模塊(當然是從PyPI:sh使用pip
)。
這是對Python subprocess
模塊功能的相當巧妙的包裝。 使用sh
您的代碼將類似於:
#!/usr/bin/python
from sh import paste
paste('file1', 'file2', 'file3', _out='result')
...盡管我認為您希望對此進行一些異常處理,所以您可以使用類似以下內容的方法:
#!/usr/bin/python
from __future__ import print_function
import sys
from sh import paste
from tempfile import TemporaryFile
with tempfile.TemporaryFile() as err:
try:
paste('file1', 'file2', 'file3', _out='result', _err=err)
except (EnvironmentError, sh.ErrorReturnCode) as e:
err.seek(0)
print("Caught Error: %s" % err.read(), file=sys.stderr)
盡管您有一些技巧,但是使用sh
可以使這些事情變得幾乎是簡單的。 您還必須注意_out=
和該形式的其他關鍵字參數之間的區別,而sh
對於大多數其他關鍵字參數而言是神奇的。
所有這一切sh
魔法使迷惑別人誰曾經讀取你的代碼。 您可能還發現,使用Python模塊, sh
隔行掃描到它的代碼使你的可移植性問題自滿。 通常,Python代碼具有相當的可移植性,而Unix命令行實用程序在一個操作系統與另一個操作系統之間,甚至從一個Linux發行版或版本到另一個操作系統,都可能有很大差異。 以這種透明的方式將大量的Shell實用程序與Python代碼交織在一起可能會使該問題不那么明顯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.