Reputation: 3340
On Linux OS, the python code below provides the directories inside the current directory.
dirs = os.popen('ls -d */').read().split(os.linesep)
print dirs
Because os.popen
is deprecated, I'm migrating this call to subprocess.Popen
proc = subprocess.Popen(['ls', '-d', '*/'], stdout=subprocess.PIPE)
outp = proc.stdout.read()
print outp
However for some reason this doesn't work, I get the following error
ls: cannot access */: No such file or directory
Upvotes: 1
Views: 1323
Reputation: 155506
*/
only works if globbing is being performed; in os.popen
, the whole string is being evaluated by a shell which is wrapping the actual ls
process, and the shell is performing the expansion. When you use the list
based Popen
, it's passing the literal string */
to ls
, and ls
doesn't expand globs on its own.
You could pass a str
and shell=True
to Popen
, but that's just reopening the performance, security and stability holes that os.popen
has. Easier is to avoid subprocesses at all, just use the glob
module or one of os.listdir
/os.scandir
/os.walk
instead of using subprocesses at all.
For example, in Python 3.5 with os.scandir
, you can get all the directories in the working directory extremely efficiently with:
import os
dirs = [x.name for x in os.scandir() if x.is_dir()]
On earlier versions of Python, os.listdir
+ os.path.isdir
can be used to do the same thing slightly less efficiently (it involves a stat
of each entry which os.scandir
can avoid, but for small directories and/or local filesystems, the stat
cost is trivial):
import os, os.path
dirs = [f for f in os.listdir('.') if os.path.isdir(f)]
Upvotes: 4