1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
# Copyright (c) 2018, Ansible Project
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
from __future__ import annotations
import os
from ansible.module_utils.common.file import is_executable
from ansible.module_utils.common.warnings import deprecate
def get_bin_path(arg, opt_dirs=None, required=None):
"""
Find system executable in PATH. Raises ValueError if the executable is not found.
:param arg: the executable to find
:type arg: string
:param opt_dirs: optional list of directories to search in addition to PATH
:type opt_dirs: list of strings
:param required: DEPRECATED. This parameter will be removed in 2.21
:type required: boolean
:returns: path to arg (should be abs path unless PATH or opt_dirs are relative paths)
:raises: ValueError: if arg is not found
In addition to PATH and opt_dirs, this function also looks through /sbin, /usr/sbin and /usr/local/sbin. A lot of
modules, especially for gathering facts, depend on this behaviour.
"""
if required is not None:
deprecate(
msg="The `required` parameter in `get_bin_path` API is deprecated.",
version="2.21",
)
paths = []
sbin_paths = ['/sbin', '/usr/sbin', '/usr/local/sbin']
opt_dirs = [] if opt_dirs is None else opt_dirs
# Construct possible paths with precedence
# passed in paths
for d in opt_dirs:
if d is not None and os.path.exists(d):
paths.append(d)
# system configured paths
paths += os.environ.get('PATH', '').split(os.pathsep)
# existing /sbin dirs, if not there already
for p in sbin_paths:
if p not in paths and os.path.exists(p):
paths.append(p)
# Search for binary
bin_path = None
for d in paths:
if not d:
continue
path = os.path.join(d, arg)
if os.path.exists(path) and not os.path.isdir(path) and is_executable(path):
# fist found wins
bin_path = path
break
if bin_path is None:
raise ValueError('Failed to find required executable "%s" in paths: %s' % (arg, os.pathsep.join(paths)))
return bin_path
|