Django:为啥当我在 django 中通过 popen 使用 Ghostscript 时会出现“找不到文件”错误

Posted

技术标签:

【中文标题】Django:为啥当我在 django 中通过 popen 使用 Ghostscript 时会出现“找不到文件”错误【英文标题】:Django: why when I use Ghostscript via popen in django do I get a "file not found" errorDjango:为什么当我在 django 中通过 popen 使用 Ghostscript 时会出现“找不到文件”错误 【发布时间】:2012-08-19 10:16:42 【问题描述】:

我正在尝试使用 ghostscript 从 Django 内部将 pdf 转换为 jpg,但是当我尝试使用 subprocess.popen 运行 ghostscript 命令时,出现“找不到文件”错误。如果我通过命令行从 py 文件运行完全相同的脚本,它可以正常工作。

这是我的脚本:

import os
import subprocess

path =  "/tmp/e15hntd/"

### this next line is what seems to cause the file not found error

sp = subprocess.Popen("gs -dSAFER -dNOPAUSE -dQUIET -dBATCH -sDEVICE=jpeg -sOUTPUTFILE=" + path + "/static.jpg " + path + "/source.pdf")

在寻找可能的解决方案后,我尝试了几个替代版本的违规行,例如:

sp = subprocess.Popen(['gs', '-dSAFER', '-dNOPAUSE', '-dQUIET', '-dBATCH', '-sDEVICE=jpeg', '-sOUTPUTFILE=' + path + "/static.jpg", path + "/source.pdf"])

或:

sp = subprocess.call("gs -dSAFER -dNOPAUSE -dQUIET -dBATCH -sDEVICE=jpeg -sOUTPUTFILE=" + path + "/static.jpg " + path + "/source.pdf")

这是完整的错误:

[Errno 2] 没有这样的文件或目录

追溯:

File "/usr/local/lib/python2.6/dist-packages/django/core/handlers/base.py" in get_response
111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/options.py" in wrapper
366.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in _wrapped_view
91.                     response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
89.         response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/sites.py" in inner
196.             return view(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in _wrapper
25.             return bound_func(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in _wrapped_view
91.                     response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in bound_func
21.                 return func(self, *args2, **kwargs2)
File "/usr/local/lib/python2.6/dist-packages/django/db/transaction.py" in inner
209.                 return func(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/options.py" in change_view
1054.                 self.save_model(request, new_object, form, True)
File "/home/Django/Update/admin.py" in save_model
41.             sp = subprocess.call("gs -dSAFER -dNOPAUSE -dQUIET -dBATCH -sDEVICE=jpeg -sOUTPUTFILE=" + unique_path + "/static.jpg " + unique_path + "/source.pdf" + unique_path + "/source.pdf")
File "/usr/lib/python2.6/subprocess.py" in call
480.     return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.6/subprocess.py" in __init__
633.                             errread, errwrite)
File "/usr/lib/python2.6/subprocess.py" in _execute_child
1139.                 raise child_exception

【问题讨论】:

您确定使用subprocess.Popen,而不是subprocess.pOpen?另外,请包括错误的完整追溯;其中有 很多 信息可以帮助您。 【参考方案1】:

您遇到的错误意味着subprocess 模块找不到它想要运行的可执行文件。

如果脚本从命令行运行,那么gs 可执行文件显然存在,所以看起来gs 可执行文件不在运行您的Django 应用程序的PATH 上。如果您改为指定 gs 的完整路径(例如 /usr/bin/gs)会有所帮助吗?

顺便说一句,如果我尝试让subprocess 启动一个不存在的可执行文件,我会收到相同的错误消息:

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.call("nonexistent")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/subprocess.py", line 493, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

编辑:如果您的进程使用命令行参数,则必须将可执行文件名称和参数指定为单独的列表项,就像您第二次尝试运行 gs 时一样:

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.call("ls /usr")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/subprocess.py", line 493, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
>>> subprocess.call(["ls", "/usr"])
bin  games  include  lib  lib32  lib64  local  sbin  share  src  X11R6
0

第一个示例不起作用,因为我的系统上没有名为 ls /usr 的可执行文件。

您能否尝试修改第二次尝试使用gs 的完整路径,例如:

sp = subprocess.Popen(['/usr/bin/gs', '-dSAFER', '-dNOPAUSE', '-dQUIET', '-dBATCH', '-sDEVICE=jpeg', '-sOUTPUTFILE=' + path + "/static.jpg", path + "/source.pdf"])

【讨论】:

我尝试使用完整路径“/usr/bin/gs”,但仍然遇到同样的错误。 我现在也尝试过使用 imagemagick,但我得到了与以前相同的子进程相关错误。 是的,明白了!感谢您的帮助:)

以上是关于Django:为啥当我在 django 中通过 popen 使用 Ghostscript 时会出现“找不到文件”错误的主要内容,如果未能解决你的问题,请参考以下文章

在 django 中通过拖放对项目进行排序

在子路径中通过 nginx+uwsgi 运行 django app

当我在同一个模型中引用一个类时,为啥 Django 会给我一个 ValueError?

如何在 Django 1.7 中通过外键将 created_by 和 updated_by 用户添加到 model.py? [复制]

django 模板中通过变量替代key取字典内容

在 Django 模板中通过变量访问字典?