2009-08-08 56 views
1

Python在中定義不是一種很好的語言,它定義了一組要運行的命令。 Bash是。但Bash不能在Windows上天真地運行。在Python中實現的便攜式命令執行語法

背景:我試圖建立一套程序 - 它們之間建立了依賴關係 - 在mac/win/linux上。像macports的東西,但應該在列出的所有三個平臺上工作。

此相生必要爲具有可被用於殼狀語言定義命令序列用於構建/修補/等。特定的程序運行,如:

post-destroot { 
    xinstall -d ${destroot}${prefix}/share/emacs/${version}/leim 
    delete ${destroot}${prefix}/bin/ctags 
    delete ${destroot}${prefix}/share/man/man1/ctags.1 
    if {[variant_isset carbon]} { 
     global version 
     delete ${destroot}${prefix}/bin/emacs ${destroot}${prefix}/bin/emacs-${version} 
    } 
} 

以上是來自emacs Portfile in macports。請注意使用變量,條件,函數..除了指定要按此順序執行的簡單命令列表。

儘管語法不是Python,但實際的執行語義必須使用子進程或其他方式推遲到Python。總之,我應該能夠'運行'這樣一個腳本..但是對於每個命令來說,一個指定的鉤子函數被調用,實際上運行任何作爲參數傳遞的命令。我希望你明白這個主意。

+0

你在這裏要求什麼?建議設計?代碼片段?請更精確。 – Pinochle 2009-08-08 15:47:40

+0

我不是要求輸入代碼片段;但關於如何實現或重新使用這樣的命令解釋器的想法(似乎macports使用Tcl) – 2009-08-08 15:57:32

回答

2

聽起來像你需要一些組合PyParsingPython Subprocess

儘管有關於它的MOTW,我發現子過程有點令人困惑,所以我使用這種包裝代碼很多。

from subprocess import Popen, PIPE 

def shell(args, input=None): 
    p = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE) 
    stdout, stderr = p.communicate(input=input) 
    return stdout, stderr 
1

斯內德爾德,在this post,列出了數十種不同的工具,你可能會選擇進行分析,在Python中,一些任意語言的(雖然我不明白爲什麼你不想使用Python本身作爲你的「定義一組命令來運行的語言」,我相信你有自己的理由)。正如Gregg所言,Ned列舉的其中一種工具是pyparsing,但還有其他三十多種工具,所以您可能希望在選擇適合自己口味的產品之前仔細查看。一旦將輸入源語言轉換爲語法樹或其他方便的內存中表示形式,就可以直接走樹並執行(插入變量值,在條件和循環等分支)。除了運行外部進程的能力外(例如通過子進程,無論是否按照Gregg的建議包裝),不要忘記,Python本身可能能夠執行一些基本命令而不會冒汗,並且在可行的情況下,這比將執行委託給一個子進程要快得多(事實上,Perl成功的一個早期動機是它可以在一個進程中完成很多事情,而sh則像瘋了一樣分離; sh等現代後代像bash和ksh吸取了教訓,現在實現了許多可以在與主腳本相同的過程中執行的內置功能;-)。

例如,您示例中的delete命令可以通過os.unlink「內部」實現(由於硬件問題,當前python.org當前已關閉,因此無法鏈接到Python在線文檔;-)。

0

這裏是我瑣碎的建議:通過正則表達式解析它到Python,使其成爲

def post_destroot(): 
    xinstall ('-d', '${destroot}${prefix}/share/emacs/${version}/leim') 
    delete ('${destroot}${prefix}/bin/ctags') 
    delete ('${destroot}${prefix}/share/man/man1/ctags.1') 
    if test('variant_isset', 'carbon'): 
     global('version') 
     delete('${destroot}${prefix}/bin/emacs', '${destroot}${prefix}/bin/emacs-${version}') 

我認爲這並不難寫xinstall()delete()test()功能,尤其是因爲Python已經有內置的功能,格式字符串"{destroot}".format(dictionary).

但爲什麼要麻煩?嘗試從標準庫中查看distutils模塊。

+0

distutils代碼是醜陋的地獄。 – 2009-08-10 21:55:11