16

I commonly use os.path.exists() to check if a file is there before doing anything with it.

I've run across a situation where I'm calling a executable that's in the configured env path, so it can be called without specifying the abspath.

Is there something that can be done to check if the file exists before calling it? (I may fall back on try/except, but first I'm looking for a replacement for os.path.exists())

btw - I'm doing this on windows.

1
  • It's not sufficient to check that it exists; you need to check that it's executable, on UNIX at least. Commented Jan 13, 2013 at 21:36

5 Answers 5

17

You could get the PATH environment variable, and try "exists()" for the .exe in each dir in the path. But that could perform horribly.

example for finding notepad.exe:

import os for p in os.environ["PATH"].split(os.pathsep): print os.path.exists(os.path.join(p, 'notepad.exe')) 

more clever example:

if not any([os.path.exists(os.path.join(p, executable) for p in os.environ["PATH"].split(os.pathsep)]): print "can't find %s" % executable 

Is there a specific reason you want to avoid exception? (besides dogma?)

Sign up to request clarification or add additional context in comments.

6 Comments

I've got existing code that i'd like to move over to accept files in the path. So it's just easier to replace os.path.exists() instead of restructing the code. :P
Thanks, I used your sample and made a function to replace os.path.exists(). Note that os.enviorn['PATH'] returns a single string, so you need to split it using the separator, in windows ";".
@monkut: and separator is in os.pathsep
To actually do this properly on Windows, you may need to account for os.environ['PATHEXT'] as well; "notepad" on Windows might mean "notepad.exe", "notepad.bat", ...
These only checks for existence, not for executability.
|
5

Extending Trey Stout's search with Carl Meyer's comment on PATHEXT:

import os def exists_in_path(cmd): # can't search the path if a directory is specified assert not os.path.dirname(cmd) extensions = os.environ.get("PATHEXT", "").split(os.pathsep) for directory in os.environ.get("PATH", "").split(os.pathsep): base = os.path.join(directory, cmd) options = [base] + [(base + ext) for ext in extensions] for filename in options: if os.path.exists(filename): return True return False 

EDIT: Thanks to Aviv (on my blog) I now know there's a Twisted implementation: twisted.python.procutils.which

EDIT: In Python 3.3 and up there's shutil.which() in the standard library.

Comments

3

Please note that checking for existance and then opening is always open to race-conditions. The file can disappear between your program's check and its next access of the file, since other programs continue to run on the machine.

Thus there might still be an exception being thrown, even though your code is "certain" that the file exists. This is, after all, why they're called exceptions.

Comments

2

You generally shouldn't should os.path.exists to try to figure out if something is going to succeed. You should just try it and if you want you can handle the exception if it fails.

Comments

0

On Unix you have to split the PATH var.

if any([os.path.exists(os.path.join(p,progname)) for p in os.environ["PATH"].split(":")]): do_something() 

1 Comment

no you don't, you need to use os.pathsep to make it work anywhere.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.