在定义要运行的命令集中,Python不是一个很好的语言。巴什是。但Bash在Windows上并不天真。
背景:我正在尝试在mac / win / linux上构建一组程序 - 它们之间建立了依赖关系。像macport这样的东西,但应该在列出的所有三个平台上工作。
这需要有一个类似shell的语言,可用于定义命令序列以运行构建/修补/等特定程序,例如:
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 :(得分:2)
听起来您需要PyParsing和Python 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 :(得分:1)
Ned Batchelder在this post中列出了几十种不同的工具,您可以选择在Python中使用某种任意语言进行解析(尽管我不太明白为什么您不想使用Python它本身就是你“定义一组命令来运行的语言”,我相信你有自己的理由)。 Ned列出的这些工具之一就是Gregg所提到的pyparsing,但是还有超过三十个其他工具,所以你可能想要在你选择一个符合你口味的产品之前先看看。
将输入源语言转换为语法树或其他方便的内存中表示后,您可以直接遍历树并执行(插入变量值,在条件和循环上分支等)。除了运行外部进程的能力(例如通过子进程,无论是否包含在Gregg建议中),不要忘记Python本身可以执行一些基本命令而不会出汗,并且,如果可行的话,这比将执行委托给子进程要快得多(事实上,Perl成功的一个早期动机是它可以在一个进程中做很多事情,而sh就像疯了一样离开;像bash和ksh这样的现代后代上了课,现在实现了许多可以在与主脚本相同的过程中执行的内置函数; - )。
例如,您的示例中的delete
命令可以通过os.unlink“内部”实现(由于HW问题,python.org目前已关闭,因此无法立即链接到Python在线文档; - 。)
答案 2 :(得分:0)
这是我的琐碎建议:通过regexp将其解析为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
模块。