User Tools

Site Tools


python:defer_to_another_program_in_the_path_if_available

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

python:defer_to_another_program_in_the_path_if_available [2012/08/29 08:43] (current)
tkbletsc created
Line 1: Line 1:
 +====== Defer to another program in the PATH if available ======
  
 +Let's say you want a custom replacement for a program on systems that don't have it, but you want to use the native binary on systems that do.  Let's further assume that you want to put one file in your path everywhere and have it do the right thing (for example, if you're sharing an NFS home directory between diverse machines). ​ The ''​defer_to_other_program()''​ function below will do that.
 +
 +<​code=python>​
 +#​!/​usr/​bin/​python
 +
 +import os,sys
 +
 +# return an array of elements from the PATH environment varible (cross-platform)
 +def get_sys_path():​
 + if sys.platform == '​win32':​
 + return os.environ['​PATH'​].split(';'​)
 + else:
 + return os.environ['​PATH'​].split(':'​)
 +
 +# find all executable binaries in the PATH environment variable with the given name, adding "​.exe"​ if necessary on Windows.
 +def find_all_in_path(filename):​
 + filename = os.path.basename(filename)
 + def isexec(p): return os.path.isfile(p) and os.access(p,​ os.X_OK)
 + is_win = sys.platform in ('​win32','​cygwin'​)
 + r=[]
 + for path in get_sys_path():​
 + t = os.path.join(path,​filename)
 + if isexec(t):
 + r.append(t)
 + elif is_win and not t.endswith('​.exe'​) and isexec(t+'​.exe'​):​
 + r.append(t+'​.exe'​)
 + return r
 +
 +# find all the other programs with the same name as this one in the path, return as an array
 +def find_other_matching_programs(filename=None):​
 + if not filename: filename = sys.argv[0]
 + if '​samefile'​ in dir(os.path): ​
 + samefile = os.path.samefile
 + else:
 + samefile = lambda a,b: os.path.abspath(a) == os.path.abspath(b) # Windows fallback
 + return [t for t in find_all_in_path(filename) if not samefile(filename,​t)]
 +
 +# if there'​s another program in the PATH with the same name (other than this one), execute it instead
 +def defer_to_other_program():​
 + m = find_other_matching_programs()
 + if m:
 + os.execv(m[0],​sys.argv)
 +
 +"""​ if we lived in a world without windows:
 +def get_sys_path_unix():​
 + return os.environ['​PATH'​].split(':'​)
 +
 +def find_all_in_path_unix(filename):​
 + return [t for t in (os.path.join(path,​os.path.basename(filename)) for path in get_sys_path()) if os.path.isfile(t) and os.access(t,​ os.X_OK)]
 +
 +def find_other_matching_programs_unix(filename=None):​
 + if not filename: filename = sys.argv[0]
 + return [t for t in find_all_in_path(filename) if not os.path.samefile(filename,​t)]
 +"""​
 +
 +defer_to_other_program()
 +</​code>​
 +
 +If you wanted to build a wrapper out of this, just put what you want to happen if the app is missing after the ''​defer_to_other_program()''​ call.
python/defer_to_another_program_in_the_path_if_available.txt ยท Last modified: 2012/08/29 08:43 by tkbletsc