Return full path of a executable or None. Symbolic links are not followed.
(exe, path=None, _cache={})
| 114 | return pythonexe |
| 115 | |
| 116 | def find_executable(exe, path=None, _cache={}): |
| 117 | """Return full path of a executable or None. |
| 118 | |
| 119 | Symbolic links are not followed. |
| 120 | """ |
| 121 | key = exe, path |
| 122 | try: |
| 123 | return _cache[key] |
| 124 | except KeyError: |
| 125 | pass |
| 126 | log.debug('find_executable(%r)' % exe) |
| 127 | orig_exe = exe |
| 128 | |
| 129 | if path is None: |
| 130 | path = os.environ.get('PATH', os.defpath) |
| 131 | if os.name=='posix': |
| 132 | realpath = os.path.realpath |
| 133 | else: |
| 134 | realpath = lambda a:a |
| 135 | |
| 136 | if exe.startswith('"'): |
| 137 | exe = exe[1:-1] |
| 138 | |
| 139 | suffixes = [''] |
| 140 | if os.name in ['nt', 'dos', 'os2']: |
| 141 | fn, ext = os.path.splitext(exe) |
| 142 | extra_suffixes = ['.exe', '.com', '.bat'] |
| 143 | if ext.lower() not in extra_suffixes: |
| 144 | suffixes = extra_suffixes |
| 145 | |
| 146 | if os.path.isabs(exe): |
| 147 | paths = [''] |
| 148 | else: |
| 149 | paths = [ os.path.abspath(p) for p in path.split(os.pathsep) ] |
| 150 | |
| 151 | for path in paths: |
| 152 | fn = os.path.join(path, exe) |
| 153 | for s in suffixes: |
| 154 | f_ext = fn+s |
| 155 | if not os.path.islink(f_ext): |
| 156 | f_ext = realpath(f_ext) |
| 157 | if os.path.isfile(f_ext) and os.access(f_ext, os.X_OK): |
| 158 | log.info('Found executable %s' % f_ext) |
| 159 | _cache[key] = f_ext |
| 160 | return f_ext |
| 161 | |
| 162 | log.warn('Could not locate executable %s' % orig_exe) |
| 163 | return None |
| 164 | |
| 165 | ############################################################ |
| 166 |