Rob Truxal Rob Truxal - 10 months ago 35
Bash Question

Need help using python subprocess module to navigate Linux directories

First off, I know there are FAR better ways to do this. I'm trying to learn the most basic behavior of subprocess.Popen() when it interacts with various UNIX commands. I'm doing something wrong with directory navigation, and I have no idea what it is. I'm running iPython as my REPL, so the ls command shows the files in the current working directory.

Someone please tell me what I'm doing wrong!

In [61]: newtree_dirs

In [62]: ls
10dir/ 1dir/ 2dir/ 3dir/ 4dir/ 5dir/ 6dir/ 7dir/ 8dir/ 9dir/

In [63]: for folder in newtree_dirs:
...: p1 = sub.Popen(['cd', './{}'.format(folder)])
...: p1.communicate()
...: foo = (i for i in xrange(10))
...: for num in foo:
...: p2 = sub.Popen(['touch', '{}file'.format(num)])
...: p2.communicate()
...: p3 = sub.Popen(['cd', '..'])
...: p3.communicate()
OSError Traceback (most recent call last)
<ipython-input-63-bb6e77faf97b> in <module>()
1 for folder in newtree_dirs:
----> 2 p1 = sub.Popen(['cd', u'./{}'.format(folder)])
3 p1.communicate()
4 bar = (i for i in xrange(10))
5 for num in bar:

after that exception, further exceptions descend into the subprocess module's error handling for a missing directory. The directory names in my cwd are identical and I don't know what's going on.

Answer Source

sub.Popen(['cd', './10dir') raises "OSError: [Errno 2] No such file or directory" because there is no such file named cd on your $PATH (and possibly on your computer at all). cd is not a stand alone executable, it's a shell builtin. If it were a stand alone executable it wouldn't be able to change the current working directory of the shell (or of your script for that matter) because a child process can't directly change it's parent's current working directory, environment variables, user id etc.

More info:
builtin vs normal command

Note: Technically to be POSIX complient in addition to the shell builtin cd an OS must provide a stand alone executable cd that changes it's own current directory and returns, but many Linux distributions don't include it. Source: Why is cd not a program?