User Tools

Site Tools


python:defer_to_another_program_in_the_path_if_available

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.

#!/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()

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

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki