Retrieving the full path of Unix apps

  • Thread starter Lorin Hochstein
  • Start date
L

Lorin Hochstein

Hello all,

I'd like to retrieve the full path of an arbitrary program on a Unix
system (e.g. gcc). What's the nicest way to do this? Currently I'm
invoking the "which" program and parsing what it outputs to determine if
the output looks like a path.

Here's what I'm currently doing. Is there a more elegant way to do this?


def fullpath(prog):
"""Compute the full path of a program"""
s = os.popen('which ' + prog).readline()[:-1]
# Confirm that the return value looks like a path
r = re.compile('/(\w+/)*' + prog)
if r.match(s) is not None:
return s
else:
raise ValueError,s



Thanks,

Lorin
 
G

Grant Edwards

I'd like to retrieve the full path of an arbitrary program on
a Unix system (e.g. gcc).

If you really have to worry about any arbitrary program, then
it's not really a solvable problem. There may be any
non-negative number of paths for a file with a particular name.
(Including zero.) Finding an exhastive list requires you to
walk the entire directory tree from the root down.
What's the nicest way to do this?

Do you care _which_ path you end up with in the case where
there are multiple ones that end in the filename of interest?

Are you assuming that the program is in one of the directories
listed in the PATH environment variable?
Currently I'm invoking the "which" program and parsing what it
outputs to determine if the output looks like a path.

Here's what I'm currently doing. Is there a more elegant way
to do this?

You could grab the value of the environment variable PATH, and
search those directories for the file in question. That's
pretty much what the 'which' command does.
 
L

Lorin Hochstein

Grant said:
Do you care _which_ path you end up with in the case where
there are multiple ones that end in the filename of interest?

Are you assuming that the program is in one of the directories
listed in the PATH environment variable?

Sorry, I should've been more clear. I am assuming the program is in one
of the directories listed in the PATH environment variable. I want the
same one that 'which' will return: the one that would get invoked if
someone just typed in the name of the program at the command-line.
You could grab the value of the environment variable PATH, and
search those directories for the file in question. That's
pretty much what the 'which' command does.

That does seem more elegant than relying on 'which'.

Thanks,


Lorin
 
A

Andrew Dalke

Lorin said:
I'd like to retrieve the full path of an arbitrary program on a Unix
system (e.g. gcc). What's the nicest way to do this? Currently I'm
invoking the "which" program and parsing what it outputs to determine if
the output looks like a path.

Here's an incomplete implementation of 'which'

import os

def is_executable(filename):
# Placeholder: not sure how to do this
return 1

def which(app):
dirnames = os.environ["PATH"].split(os.path.pathsep)
for dirname in dirnames:
filename = os.path.join(dirname, app)
if (os.path.exists(filename) and
os.path.isfile(filename) and
is_executable(filename)):
return filename
return None

Andrew
(e-mail address removed)
 
M

Michael Hoffman

Lorin said:
That does seem more elegant than relying on 'which'.

I dunno. I imagine that after a certain point, relying on 'which' will
be faster since it is written in C. You're going to have to do process a
lot of stats to find out which files you have execute permission for.
And they have already dealt with all the caveats that you haven't even
thought of yet ;-)
 
A

Andrew Dalke

Michael said:
You're going to have to do process a
lot of stats to find out which files you have execute permission for.
And they have already dealt with all the caveats that you haven't even
thought of yet ;-)

OTOH, if the path or filename contains a "\n" then the
OP's code won't work. If the filesystem uses Unicode then
there will also be problems.

Andrew
(e-mail address removed)
 
N

Nick Craig-Wood

Andrew Dalke said:
Here's an incomplete implementation of 'which'

import os

def is_executable(filename):
# Placeholder: not sure how to do this
return 1

def is_executable(filename):
return os.access(filename, os.X_OK)

Is probably close enough unless you are running setuid (and even then
it probably does the right thing!)
def which(app):
dirnames = os.environ["PATH"].split(os.path.pathsep)
for dirname in dirnames:
filename = os.path.join(dirname, app)
if (os.path.exists(filename) and
os.path.isfile(filename) and
is_executable(filename)):
return filename
return None
 
A

Andrew Dalke

Nick said:
def is_executable(filename):
return os.access(filename, os.X_OK)

Ahh. Didn't know about 'access'. Looks like I
could change

into

if (os.access(filename, os.X_OK) and
os.path.isfile(filename)):

because access returns false if the file/directory
doesn't exist.

Andrew
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top