如何在 setup.py 中执行(安全的)bash shell 命令?

aza*_*tar 3 python setuptools nunjucks

我使用 nunjucks 在 python 项目中模板化前端。Nunjucks 模板必须在生产中预编译。我不在 nunjucks 模板中使用扩展或异步过滤器。与其使用 grunt-task 来监听模板的变化,我更喜欢使用 nunjucks-precompile 命令(通过 npm 提供)将整个模板目录扫描到 templates.js 中。

这个想法是让nunjucks-precompile --include ["\\.tmpl$"] path/to/templates > templates.js命令在 setup.py 中执行,这样我就可以简单地搭载我们的部署程序脚本的常规执行。

我发现setuptools 覆盖distutils 脚本参数可能用于正确的目的,但我不太确定这两个是最简单的执行方法。

另一种方法是使用subprocess直接在 setup.py 中执行命令,但我已被警告不要这样做(而是先发制人,恕我直言)。我真的不明白为什么不。

有任何想法吗?肯定?确认?

更新 (04/2015): - 如果您没有nunjucks-precompile可用的命令,只需使用 Node Package Manager 安装 nunjucks,如下所示:

$ npm install nunjucks
Run Code Online (Sandbox Code Playgroud)

aza*_*tar 6

原谅快速的自我回答。我希望这可以帮助以太坊中的某个人。我想分享这个,因为我已经找到了一个我满意的解决方案。

这是一个安全的解决方案,基于Peter Lamut 的文章。请注意,这并没有在子进程调用使用shell =真。您可以绕过 Python 部署系统上的 grunt-task 要求,也可以使用它进行混淆和 JS 打包。

from setuptools import setup
from setuptools.command.install import install
import subprocess
import os

class CustomInstallCommand(install):
    """Custom install setup to help run shell commands (outside shell) before installation"""
    def run(self):
        dir_path = os.path.dirname(os.path.realpath(__file__))
        template_path = os.path.join(dir_path, 'src/path/to/templates')
        templatejs_path = os.path.join(dir_path, 'src/path/to/templates.js')
        templatejs = subprocess.check_output([
            'nunjucks-precompile',
            '--include',
            '["\\.tmpl$"]',
            template_path
        ])
        f = open(templatejs_path, 'w')
        f.write(templatejs)
        f.close()
        install.run(self)

setup(cmdclass={'install': CustomInstallCommand},
      ...
     )
Run Code Online (Sandbox Code Playgroud)