Source code for realtwin.util_lib.find_exe_from_PATH

##############################################################################
# Copyright (c) 2024, Oak Ridge National Laboratory                          #
# All rights reserved.                                                       #
#                                                                            #
# This file is part of RealTwin and is distributed under a GPL               #
# license. For the licensing terms see the LICENSE file in the top-level     #
# directory.                                                                 #
#                                                                            #
# Contributors: ORNL Real-Twin Team                                          #
# Contact: realtwin@ornl.gov                                                 #
##############################################################################
import os
import subprocess
from typing import Optional
import pyufunc as pf


[docs] def find_executable_from_PATH_on_win(exe_name: str, ext: str = "exe", sel_dir: list = None, verbose: bool = True) -> list | None: """Find the executable from the system PATH. Args: exe_name (str): The executable name to search for. ext (str): The extension of the executable. Defaults to "exe" for executable files. sel_dir (list): A list of directories to search for the executable. Defaults to []. verbose (bool): Whether to print the process info. Defaults to True. Returns: list or None: A list of full path of the executable if found, otherwise None. """ # check if the executable name is a string if not isinstance(exe_name, str): raise ValueError("exe_name should be a string.") # check if extension is str if not isinstance(ext, str): raise ValueError("ext should be a string.") # check if sel_dir is a list if not isinstance(sel_dir, (list, type(None))): raise ValueError("sel_dir should be a list.") # Add the selected directories to the PATH environment if sel_dir: for path in sel_dir: if os.path.isdir(path): os.environ["PATH"] += os.pathsep + path elif verbose: print(f" :The directory: {path} does not exist. Skipped.") # check if exe_name has the extension _, ext_str = os.path.splitext(exe_name) if not ext_str: if verbose: print(f" :The executable: {exe_name} has no extension. Added {ext} as the extension.") exe_name = f"{exe_name}.{ext}" # get the full environment PATH env_paths = os.getenv("PATH").split(os.pathsep) res = [] for path in env_paths: abs_path = pf.path2linux(os.path.join(path, exe_name)) # check if the file exists and is executable if os.path.isfile(abs_path) and os.access(abs_path, os.X_OK): res.append(abs_path) if not res: if verbose: print(f" :Could not find {exe_name} in the system PATH." " Please make sure the executable is installed." " please include executable extension in the name.") return None if verbose: print(f" :Found {exe_name} in the system PATH:") for path in res: print(f" :{path}") return res
def find_executable_from_PATH_on_linux(exe_name: str, verbose: bool = True) -> list[str]: """Use the system `which -a` to list all matches for exe_name on Linux. Args: exe_name (str): The name of the executable to search for. verbose (bool): Whether to print the process info. Defaults to True. Example: >>> find_executable_from_PATH_on_linux("python3", verbose=True) >>> ['/usr/bin/python3', '/usr/local/bin/python3'] Returns: Optional[List[str]]: A list of paths where the executable is found, or None if not found. """ try: # -a: list all matches, not just the first proc = subprocess.run( ["which", "-a", exe_name], capture_output=True, text=True, check=False) paths = [line.strip() for line in proc.stdout.splitlines() if line.strip()] if verbose: if paths: for p in paths: print(f"[which] Found: {p}") else: print(f"[which] No matches for {exe_name}") return paths or None except FileNotFoundError: if verbose: print("[which] `which` command not found on this system.") return None