Subprocess changing directory

Posted on

Question :

Subprocess changing directory

I want to execute a script inside a subdirectory/superdirectory (I need to be inside this sub/super-directory first). I can’t get subprocess to enter my subdirectory:

tducin@localhost:~/Projekty/tests/ve$ python
Python 2.7.4 (default, Sep 26 2013, 03:20:26) 
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> import os
>>> os.getcwd()
>>>['cd ..'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/", line 524, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/", line 711, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/", line 1308, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

Python throws OSError and I don’t know why. It doesn’t matter whether I try to go into an existing subdir or go one directory up (as above) – I always end up with the same error.

Asked By: ducin


Answer #1:

What your code tries to do is call a program named cd ... What you want is call a command named cd.

But cd is a shell internal. So you can only call it as'cd ..', shell=True) # pointless code! See text below.

But it is pointless to do so. As no process can change another process’s working directory (again, at least on a UNIX-like OS, but as well on Windows), this call will have the subshell change its dir and exit immediately.

What you want can be achieved with os.chdir() or with the subprocess named parameter cwd which changes the working directory immediately before executing a subprocess.

For example, to execute ls in the root directory, you either can do

wd = os.getcwd()

or simply

subprocess.Popen("ls", cwd="/")
Answered By: glglgl

Answer #2:

To run your_command as a subprocess in a different directory, pass cwd parameter, as suggested in @wim’s answer:

import subprocess

subprocess.check_call(['your_command', 'arg 1', 'arg 2'], cwd=working_dir)

A child process can’t change its parent’s working directory (normally). Running cd .. in a child shell process using subprocess won’t change your parent Python script’s working directory i.e., the code example in @glglgl’s answer is wrong. cd is a shell builtin (not a separate executable), it can change the directory only in the same process.

Answered By: jfs

Answer #3:

You want to use an absolute path to the executable, and use the cwd kwarg of Popen to set the working directory. See the docs.

If cwd is not None, the child’s current directory will be changed to
cwd before it is executed. Note that this directory is not considered
when searching the executable, so you can’t specify the program’s path
relative to cwd.

Answered By: wim

Answer #4: and other methods in the subprocess module have a cwd parameter.

This parameter determines the working directory where you want to execute your process.

So you can do something like this:'ls', shell=True, cwd='path/to/wanted/dir/')

Check out docs subprocess.popen-constructor

Answered By: l__flex__l

Answer #5:

Another option based on this answer:

This allows you to execute multiple commands (e.g cd) in the same process.

import subprocess

commands = '''
cd some-directory
cd another-directory

process = subprocess.Popen('/bin/bash', stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, err = process.communicate(commands.encode('utf-8'))
Answered By: Eyal Levin

Answer #6:

I guess these days you would do:

import subprocess["pwd"], cwd="sub-dir")
Answered By: Francois

Answer #7:

If you want to have cd functionality (assuming shell=True) and still want to change the directory in terms of the Python script, this code will allow ‘cd’ commands to work.

import subprocess
import os

def cd(cmd):
    #cmd is expected to be something like "cd [place]"
    cmd = cmd + " && pwd" # add the pwd command to run after, this will get our directory after running cd
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) # run our new command
    out =
    err =
    # read our output
    if out != "":
        os.chdir(out[0:len(out) - 1]) # if we did get a directory, go to there while ignoring the newline 
    if err != "":
        print(err) # if that directory doesn't exist, bash/sh/whatever env will complain for us, so we can just use that
Answered By: Tactical Tux

Answer #8:

just use os.chdir

>>> import os
>>> import subprocess
>>> # Lets Just Say WE want To List The User Folders
>>> os.chdir("/home/")
user1 user2 user3 user4
Answered By: Harsha Addanki

Leave a Reply

Your email address will not be published. Required fields are marked *