尝试使用子进程(Django)执行Python脚本

尝试使用子进程(Django)执行Python脚本,python,django,subprocess,Python,Django,Subprocess,我正在尝试使用子流程执行脚本,当我手动执行它时,我知道子流程是有效的;以下是我的调用脚本: # the command string we want to issue to ffmpeg.py to generate our ffmpeg command strings commandString = [ 'python', os.path.join(SCRIPT_DIR, 'ffmpeg.py'), '-i

我正在尝试使用子流程执行脚本,当我手动执行它时,我知道子流程是有效的;以下是我的调用脚本:

# the command string we want to issue to ffmpeg.py to generate our ffmpeg command strings
        commandString = [
            'python',
            os.path.join(SCRIPT_DIR, 'ffmpeg.py'),
            '-i', os.path.join('/srv/nfsshare/transcode50', userFolder, directory, title),
            '-d', os.path.join('/srv/nfsshare/transcode50', userFolder, directory),
            '-r', request.POST['framerate'],
            '-p 2', '-f', ",".join(formats), '-t', ",".join(rasters)
        ]

        # call transcode50 script to generate condor_execute.py
        subprocess.call(' '.join(commandString) + ' > /srv/nfsshare/transcode50/output.txt', shell=True)

实际的脚本本身本质上会生成一个命令字符串列表,并将它们输出到控制台。我通过管道将输出传输到命令字符串末尾名为output.txt的文件来测试这一点,因为我正在从Django运行Python代码,无法实时查看shell输出,但每次检查该文件时,都没有任何内容,并且调用的脚本也没有产生副作用(生成Python文件)。因此,我相信我可能会考虑使用子流程模块,也可能不会考虑使用子流程模块,而且可能是Django特有的?

使用“”将列表转换为shell字符串是有风险的,因为列表中可能有某些内容(如文件名中的空格)需要shell转义。您最好只使用命令列表,而不是shell。您还应该捕获stderr,这是好东西将要出现的地方。最后使用check_调用并将整个过程包装到一个记录执行失败的异常处理程序中

try:
    commandString = [
        'python',
        os.path.join(SCRIPT_DIR, 'ffmpeg.py'),
        '-i', os.path.join('/srv/nfsshare/transcode50', userFolder, directory, title),
        '-d', os.path.join('/srv/nfsshare/transcode50', userFolder, directory),
        '-r', request.POST['framerate'],
        '-p 2', '-f', ",".join(formats), '-t', ",".join(rasters)
    ]

    # call transcode50 script to generate condor_execute.py
    subprocess.check_call(commandString, 
        stdout=open('/srv/nfsshare/transcode50/output.txt', 'w'),
        stderr=subprocess.STDOUT)

except Exception, e:
    # you can do fancier logging, but this is quick
    open('/tmp/test_exception.txt', 'w').write(str(e))
    raise

为什么要作为子流程调用来执行此操作,而不是简单地导入脚本并调用它?我可以导入此脚本,这可能会起作用,但它将生成一个新的Python脚本,需要以任何方式运行,因此执行新脚本时仍需解决此问题,除非您有任何关于在“会话”开始后运行生成的Python脚本的建议(即,保存一个新的script.py文件,但仍然能够从生成该文件的同一脚本中打开并执行该文件),否则您可能会丢失stderr,这可能会解释发生了什么。