Reputation: 9956
I am trying to use ghostscript to convert a pdf to jpg from inside Django, but when I try to use subprocess.popen to run a ghostscript command I get a "file not found" error. If I run exactly the same script from a py file via the command line it works correctly.
Here is my script:
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")
after searching around for possible solutions I tried several alternative versions of the offending line e.g.:
sp = subprocess.Popen(['gs', '-dSAFER', '-dNOPAUSE', '-dQUIET', '-dBATCH', '-sDEVICE=jpeg', '-sOUTPUTFILE=' + path + "/static.jpg", path + "/source.pdf"])
or:
sp = subprocess.call("gs -dSAFER -dNOPAUSE -dQUIET -dBATCH -sDEVICE=jpeg -sOUTPUTFILE=" + path + "/static.jpg " + path + "/source.pdf")
Here is the full error:
[Errno 2] No such file or directory
Traceback:
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
Upvotes: 1
Views: 1209
Reputation: 64959
The error you're getting means that the subprocess
module cannot find the executable it wants to run.
If the script runs from the command-line then the gs
executable clearly exists, so it looks like the gs
executable is not on the PATH
that your Django application is running with. Does it help if you specify the full path to gs
(e.g. /usr/bin/gs
) instead?
Incidentally, I get the same error message if I try to get subprocess
to start a nonexistent executable:
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
EDIT: if your process uses command-line arguments, the executable name and the argument must be specified as separate list items, as in the second of your attempts at running 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
The first example didn't work because I don't have an executable named ls /usr
anywhere on my system.
Could you try modifying the second of your attempts to use the full path of gs
, for example:
sp = subprocess.Popen(['/usr/bin/gs', '-dSAFER', '-dNOPAUSE', '-dQUIET', '-dBATCH', '-sDEVICE=jpeg', '-sOUTPUTFILE=' + path + "/static.jpg", path + "/source.pdf"])
Upvotes: 2