0

手動で実行すると機能することがわかっているサブプロセスを使用してスクリプトを実行しようとしています。以下は私の呼び出しスクリプトからのものです:

# 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)

実際のスクリプト自体は、基本的にコマンド文字列のリストを生成し、それらをコンソールに出力します。DjangoからPythonコードを実行していて、シェル出力をリアルタイムで見ることができないため、これをテストするために、そのコマンド文字列の最後にあるoutput.txtというファイルに出力をパイプしましたが、ファイルをそれぞれ調べると時間、そこには何もなく、呼び出されたスクリプトにもある副作用 (Python ファイルの生成) は発生しません。したがって、 subprocess モジュールの使用を検討している場合と検討していない場合があると思いますが、おそらくそれは Django 固有のものでしょうか?

4

1 に答える 1

1

' '.join(...) を使用してリストをシェル文字列に変換することは危険です。なぜなら、シェル エスケープが必要な何か (ファイル名のスペースなど) がリストに含まれている可能性があるためです。シェルではなく、コマンドリストに固執する方がよいでしょう。また、良いものがある場所であるstderrをキャプチャする必要があります。最後に check_call を使用して、実行の失敗をログに記録する例外ハンドラーに全体をラップします。

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
于 2013-10-23T22:05:53.453 に答える