2009-08-08 75 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