Liondancer
Liondancer

Reputation: 16479

Running commands/programs with subprocess

I am new to the subprocess module in python.

The documentation provided this example:

>>> subprocess.check_output(["echo", "Hello World!"])
b'Hello World!\n'

What I tried is:

>>> import subprocess
>>> subprocess.check_output(["cd", "../tests", "ls"])
/usr/bin/cd: line 4: cd: ../tests: No such file or directory
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/subprocess.py", line 620, in check_output
    raise CalledProcessError(retcode, process.args, output=output)
subprocess.CalledProcessError: Command '['cd', '../tests', 'ls']' returned non-zero exit status 1

I am confused because this is my file structure:

   /proj
      /cron
         test_scheduler.py
      /tests
         printy.py
         test1.py
         test2.py
         ...

These are my other attempts as well:

>>> subprocess.check_output(["cd", "../tests", "python", "printy.py"])
/usr/bin/cd: line 4: cd: ../tests: No such file or directory
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/subprocess.py", line 620, in check_output
    raise CalledProcessError(retcode, process.args, output=output)
subprocess.CalledProcessError: Command '['cd', '../tests', 'python', 'printy.py']' returned non-zero exit status 1


>>> subprocess.check_output(["cd", "../tests;", "ls"])
/usr/bin/cd: line 4: cd: ../tests;: No such file or directory
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/subprocess.py", line 620, in check_output
    raise CalledProcessError(retcode, process.args, output=output)
subprocess.CalledProcessError: Command '['cd', '../tests;', 'ls']' returned non-zero exit status 1

Upvotes: 1

Views: 6766

Answers (4)

UltraInstinct
UltraInstinct

Reputation: 44464

Try to avoid shell=True if possible.

In this case, you can certainly avoid. The problem you are facing is: cd is a shell builtin. Its not a command/program/utility that can be called from outside. You need to be within a shell for cd to work. What you can instead do is change your current directory. Execute the command. And then go back to your original directory.

You'll need to do something like the below:

pathBefore = os.getcwd()
os.chdir("/path/to/your/directory")
subprocess.check_output(["ls"])
os.chdir(pathBefore) # get back to the path we were in before

UPDATE: A better approach pointed out by @JFSebastian is to use the additional cwd argument to check_output call.

Upvotes: 3

jfs
jfs

Reputation: 414865

The error message is clear:

/usr/bin/cd: line 4: cd: ../tests: No such file or directory

that is you have successfully started /usr/bin/cd program that failed and printed the error message.

If you wanted to run ls command from ../tests directory instead:

import os
import subprocess

cwd = os.path.join(get_script_dir(), '../tests')
output = subprocess.check_output(['ls'], cwd=cwd)

where get_script_dir().

Note: do not use a relative path for the directory -- your script can be run from a different directory -- relative paths fail in this case.

Upvotes: 1

BitTickler
BitTickler

Reputation: 11947

You are missing a argument here I think.
Here a snippet from the only python script I ever wrote:

#!/usr/local/bin/python

from subprocess import call
...
call( "rm " + backupFolder + "*.bz2", shell=True )

Please note the shell=True in the end of that call.

Upvotes: 0

NicolasP
NicolasP

Reputation: 764

The relative path to the tests directory depends on where the script is being run from. I would suggest calling subprocess.check_output(["pwd"]) to check where you are.

Also you can't combine two commands in the same call like in your attempt with ["cd", "../tests", "python", "printy.py"]. You'll need to make two separate calls with ["cd", "../tests"] and ["python", "printy.py"] respectively.

Upvotes: 1

Related Questions