6

I'm coding a Python script which is using the application pdftk a few times to perform some operations.

For example, I can use pdftk in the windows command line shell to merge two pdf files like this:

pdftk 1.pdf 2.pdf cat output result.pdf

I would like to perform the above operation in the middle of my Python script. Here's how I tried doing it:

os.system('pdftk 1.pdf 2.pdf cat output result.pdf')

The above pdftk command works perfectly in the Windows shell. However, it fails to open the input files (1.pdf and 2.pdf) when I'm trying to execute it using Python's os.system(). Here's the error message I get from pdftk when trying to execute the command using Python's os.system():

Error: Failed to open PDF file: 1.pdf

Error: Failed to open PDF file: 2.pdf

Why does it happen? How can I fix it?

Please note: I know there are better ways to merge pdf files with Python. My question isn't about merging pdf files. That was just a toy example. What I'm trying to achieve is an ability to execute pdftk and other command line applications using Python.

snakile
  • 52,936
  • 62
  • 169
  • 241
  • 4
    It's almost certainly an issue with the directory paths. You could pass in the full path from `C:\` or wherever it is, or make sure you're starting in the right directory. – chmullig Feb 02 '11 at 23:15
  • It can also be a quoting or shell variable interpolation issue. Always use the `subprocess` module instead of `os.system` to avoid such issues. – Philipp Feb 02 '11 at 23:28
  • 3
    @chmullig: Do you really thing I'm that stupid? Well, turns out I am. The problem was indeed a path issue. Please repeat what you said in an answer to the question and I'll accept it. Thanks. – snakile Feb 02 '11 at 23:29
  • @Philipp: Could you please expand your remark on using subprocess instead of os.system? Why? What's the difference? Thanks. – snakile Feb 02 '11 at 23:31
  • by default, subprocess does not invoke a shell [so no variable expansion, etc]. Thus shell injection attacks fail. – Foo Bah Feb 02 '11 at 23:48
  • @sna: `os.system` uses the shell, which requires arguments to be quotes in non-portable ways. The classes and functions in the `subprocess` module usually launch the process directly. See http://stackoverflow.com/questions/4813238. – Philipp Feb 02 '11 at 23:50
  • What's with this recent trend of answering questions with comments? If you have an answer, POST AN ANSWER! – dkamins Feb 03 '11 at 02:38

3 Answers3

3

You need to set the current working directory of the process. If the .pdf files are located at /some/path/to/pdf/files/:

>>> os.getcwd()
'/home/vz0'
>>> os.chdir('/some/path/to/pdf/files/')
vz0
  • 32,345
  • 7
  • 44
  • 77
3

You can avoid (potential) problems with quoting, escaping, and so on, with subprocess:

import subprocess

subprocess.call(['pdftk', '1.pdf', '2.pdf', 'cat', 'output', 'result.pdf'])

It's just as easy to use as os.system, and even easier if you are building the argument list dynamically.

Danilo Piazzalunga
  • 7,590
  • 5
  • 49
  • 75
0

Make sure you are in the same current working directory.

Also I found using \\ instead of / helped me.

stackprotector
  • 10,498
  • 4
  • 35
  • 64
michaelobr
  • 21
  • 3