|  | #!/bin/bash | 
|  |  | 
|  | # This script is a wrapper for programs that may have alternate versions (e.g. python2, python3).  This | 
|  | # wrapper allows the user to influence the selection of the program version by setting the <program | 
|  | # name>_VERSION (e.g. PYTHON_VERSION, ROBOT_VERSION, etc.) environment variable. | 
|  |  | 
|  | # Users would be expected to create a link with the base name of the program that points to this file. | 
|  |  | 
|  | # Example: | 
|  | # cd openbmc-test-automation/bin | 
|  | # ln -s select_version python | 
|  |  | 
|  | # The PATH variable should contain the expanded path to openbmc-test-automation/bin. | 
|  |  | 
|  | # If <program name>_VERSION is blank or not set, then the program version will be whatever the system | 
|  | # default program version is.  If <program name>_VERSION is set to a value, then that value will be appended | 
|  | # to the name of the program (e.g. if PYTHON_VERSION = "3", then python3 will be used.).  If <program | 
|  | # name>_VERSION is set to some value that does not correspond to a valid program version for the given | 
|  | # system, this program will fail. | 
|  |  | 
|  |  | 
|  | # Make sure program_name is set. | 
|  | program_name="${0##*/}" | 
|  | program_uppercase_name=${program_name^^} | 
|  |  | 
|  |  | 
|  | function get_target_program_path() { | 
|  | local target_program_path_var="${1:-target_program_path}" ; shift | 
|  |  | 
|  | # Get the full path to the "real" program and assign it to the variable named in target_program_path_var. | 
|  |  | 
|  | # Description of argument(s): | 
|  | # target_program_path_var         The name of the variable to receive the result. | 
|  |  | 
|  | # Example result: | 
|  |  | 
|  | # /usr/bin/python3 | 
|  |  | 
|  | local version_var_name | 
|  | local alternate_program_name | 
|  | local base_program_path | 
|  | local base_program_name | 
|  | local candidate | 
|  | local candidates | 
|  | local base_file_path | 
|  |  | 
|  | # The typical use of this program would be to create a link to it like this: | 
|  | # ln -s select_version python | 
|  | # That being the case, get the name of this actual program (rather than the name of the link to it). | 
|  | base_program_path=$(readlink -f "${0}") | 
|  | base_program_name=${base_program_path##*/} | 
|  |  | 
|  | if [ "${program_name}" == "${base_program_name}" ] ; then | 
|  | { | 
|  | echo -n "**ERROR** ${base_program_name} should never be called directly." | 
|  | echo "  Only links to ${base_program_name} should be called." | 
|  | } >&2 | 
|  | exit 1 | 
|  | fi | 
|  |  | 
|  | # Compose the version_var_name value (e.g. PYTHON_VERSION). | 
|  | version_var_name=${program_uppercase_name}_VERSION | 
|  | # Compose the alternate_program_name (e.g. python3). | 
|  | alternate_program_name=${program_name}${!version_var_name} | 
|  |  | 
|  | # Now use the "type" built-in to search the PATH variable for a list of target program candidates. | 
|  | candidates=$(type -ap ${alternate_program_name}) | 
|  |  | 
|  | # Example candidates: | 
|  | # /home/robot/openbmc-test-automation/bin/python | 
|  | # /usr/bin/python | 
|  |  | 
|  | # In this example, the first candidate is actually a link to | 
|  | # /home/robot/openbmc-test-automation/bin/select_version.  As such it will be rejected. | 
|  |  | 
|  | for candidate in ${candidates} | 
|  | do | 
|  | if [ -L "${candidate}" ] ; then | 
|  | # The candidate is a link so we need to see if it's a link to this program file. | 
|  | base_file_path=$(readlink "${candidate}") | 
|  | [ "${base_file_path}" == "${base_program_name}" ] && continue | 
|  | fi | 
|  |  | 
|  | # The candidate is NOT a link so it qualifies as the desired target program path. | 
|  | eval ${target_program_path_var}=\"\${candidate}\" | 
|  | return | 
|  |  | 
|  | done | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  | # Main | 
|  |  | 
|  | get_target_program_path target_program_path | 
|  |  | 
|  | # Compose program path var name (e.g. PYTHON_PGM_PATH). | 
|  | pgm_path_var_name=${program_uppercase_name}_PGM_PATH | 
|  | # Set and export pgm_path_var_name (e.g. PYTHON_PGM_PATH=/usr/bin/python3).  This value can be used by | 
|  | # child programs for debug. | 
|  | eval export ${pgm_path_var_name}=${target_program_path} | 
|  |  | 
|  | if [ "${1}" == "--print_only" ] ; then | 
|  | echo "${target_program_path}" | 
|  | else | 
|  | # Use exec in order to replace this process with the target process. | 
|  | exec ${target_program_path} "${@}" | 
|  | fi | 
|  |  |