从python运行时wkhtmltopdf段错误

时间:2014-12-05 08:41:10

标签: python subprocess openerp wkhtmltopdf odoo

我必须使用subprocess.call(...)从python运行wkhtmltopdf。从命令行,我可以毫无问题地生成pdf,但是当它从python运行时,它会失败并出现段错误。

我不知道导致wkhtmltopdf导致段错误的原因。

我甚至尝试发送我的终端env属性,但它仍然是段错误。我发送了stderr,stdin,stdout,但没有任何作用。令我担心的是它从终端运行而不是从python运行。

另外,在python中从不同进程调用进程也会使其成为段错误。例如,我在其间添加了一个脚本来调用这个应用程序,用python编写的脚本也从wkhtmltopdf接收段错误。

#!/bin/env python
import subprocess
import sys
import pdb
import os


sys.argv[0] = "/usr/local/bin/wkhtmltopdf.b"

sys.argv.remove('--quiet')

status = subprocess.call(sys.argv,
    env=env,
    stdin=sys.stdin,
    stdout=open("/tmp/stdout.w", "w"),
    stderr=open("/tmp/stderr.w", "w"))

cmd = " ".join(sys.argv)

pdb.set_trace()

现在我这样做是为了让我有时间在外部终端执行命令。 OpenErp正在检查pdf文件的内容。 wkhtmltopdf.b是原始二进制文件。我删除了quiet参数,因为我想知道发生了什么。

此刻显然是段错误:

Loading pages (1/6)
[======>                                                     ] 10%

没有别的

我的版本wkhtmltopdf amd64 static来自网站wkhtmltopdf.org

$ wkhtmltopdf -V
wkhtmltopdf 0.12.1 (with patched qt)

我在我的gentoo盒子上运行了一个ubuntu amd64二进制包。在gentoo上使用修补的qt编译wkhtmltopdf很难/很长时间它似乎默认不受支持。然而,既然它从命令行运行,它也应该从python运行。

我从zsh运行它,但即使在我的python程序中,我也会调用这样的东西:

'/bin/sh -c "%s"' % command

它也会出现段错误。

2 个答案:

答案 0 :(得分:1)

我遇到的问题和你的问题完全相同,但运行的是不同的堆栈(Apache和PHP),但我并不是100%确定你是如何启动你的python的。无论如何,它在你的同一个地方完全崩溃,并且从命令行运行良好,所以我想这可能值得分享以防万一;)

我发现我的问题是在通过apache然后shell运行时设置的ulimit不同。特别是我的虚拟内存" ulimit -v非常低。我最终做了$ cmd =" ulimit -v 1073741824; {$这 - > wkhtmltopdf_path} ...."这解决了我的问题! (您可以检查运行ulimit -a并比较shell上相同命令的值!)

答案 1 :(得分:0)

尝试通过stdin传递HTML字符串。这是一个示例,然后是下载响应。

from subprocess import Popen, PIPE, STDOUT
from django.core.files.temp import NamedTemporaryFile
from django.template.loader import render_to_string
from django.http import HttpResponse

tmp = NamedTemporaryFile()
html = render_to_string('your-template.html', context)
p = Popen(['wkhtmltopdf', '-', tmp.name], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
out, err = p.communicate(input=(html + u'\n').encode('utf-8'))
# check for errors in 'out' and 'err' -- print out, err
with open(tmp.name, 'r') as pdf:
    pdfcontent = pdf.read()
response = HttpResponse(pdfcontent, content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename=print.pdf'
response['Content-Length'] = len(pdfcontent)
return response

您必须在模板中使用完整的静态网址,以防止wkhtmltopdf无法找到静态CSS和JS文件。