1

Using Python's subprocess.call, I am trying to invoke a C program that reads an input file on disk, and creates multiple output files. Running the C program from terminal gives the expected results, though subprocess.call does not.

In the minimal example, the program should read the input file in a scratch folder, and create an output file in the same folder. The locations and names of the input & output files are hardcoded into the C program.

import subprocess


subprocess.call('bin/program.exe') # parses input file 'scratch/input.txt'
with open('scratch/output.txt') as f:
    print(f.read())

This returns:

FileNotFoundError: [Errno 2] No such file or directory: 'scratch/output.txt'

What am I doing wrong?

Using subprocess.check_output, I see no errors.

EDIT: So I see the subprocess working directory is involved. The C executable has hardcoded paths for input/output relative to the exe (ie, '../scratch/input.txt'), but the subprocess.call() invocation required paths relative to the python script, not the exe. This is unexpected, and produces very different results from invoking the exe from the terminal.

Valarauko
  • 111
  • 1
  • 4
  • I will suggest to use "import commands"; using this you will also get output of you C program(you can run it normal way you runs in gcc), and if failure the status code will change. eg. output = commands.getstatusoutput("gcc test.c") – abhijeetmote Sep 28 '16 at 08:14
  • @abhijeetmote the `commands` module is made obsolete by the `subprocess` module. – Valarauko Sep 28 '16 at 08:41

1 Answers1

1
import os

subprocess.call('bin/program.exe') # parses input file 'scratch/input.txt'
if not os.path.isfile('scratch'):
    os.mkdir('scratch')
with open(os.path.join('scratch','output.txt'), 'w') as f:
    f.write('Your message')

You have to open the file in a mode. Read for example. You will need to join the path with os.path.join().

You can create a folder and a file if they don't exist. But there will bo nothing to read from. If you want to write to them, that can be acheived like shown above.

Daniel Lee
  • 7,189
  • 2
  • 26
  • 44
  • If file mode isn't specified, it should default to read. Besides, the problem isn't in reading the output file, it's that the output isn't created. – Valarauko Sep 28 '16 at 08:32
  • You can't read from a file that doesn't exist - regardless, I updated my answer to create a file and folder that you can write to. – Daniel Lee Sep 28 '16 at 08:48
  • I appreciate that while a non-existent file can't be read, my concern is with *why* the output file isn't being created. Invoking the C program from the terminal creates the expected output file in the scratch folder, while invoking it though `subprocess.call` creates no output file. The locations and names of the input & output files are hardcoded into the C program. `subprocess.check_output` also yields no errors, unlike if I remove the input file, in which case `check_output` contains the C program's relevant error message. – Valarauko Sep 28 '16 at 09:01
  • Apologies, try `print subprocess.call()` or do a check `if subprocess.call()!=0 print 'failure'` it also may need more time to finish running the exe. In that case, you can wait for it to finish with `while subprocess.call != 0: pass` – Daniel Lee Sep 28 '16 at 09:07
  • My understanding of `subprocess` is that by default it waits for the subprocess to complete, before proceeding. Besides, if I reduce the script to only invoke the subprocess, and remove the attempt to read the output, it still completes, with no output file created. – Valarauko Sep 28 '16 at 09:19
  • have you tried `subprocess.call(["C:\pathToYourProgram\yourProgram.exe"])` – Daniel Lee Sep 28 '16 at 09:28
  • All the [answers from here](http://stackoverflow.com/questions/1811691/running-an-outside-program-executable-in-python) use the `[]`notation. – Daniel Lee Sep 28 '16 at 09:30
  • Yes, [] makes no difference. – Valarauko Sep 28 '16 at 11:02