#!/usr/bin/env bash # read from file if provided, else from stdin if [[ -f $1 ]]; then exec 0<"$1" fi print_red() { printf "\e[31;1m$1\e[0m" } print_yellow() { printf "\e[33;1m$1\e[0m" } print_orange() { printf "\e[33m$1\e[0m" } print_purple() { printf "\e[35;1m$1\e[0m" } colour_errors() { perl -pne "s/(err(?:or)?:)/$(print_red '\\1')/gi;s/(warn(?:ing)?:)/$(print_orange '\\1')/gi;s/(^|\\033\[0m)(.+?)(?=\\033|$)/\1$(print_yellow '\\2')/gi" } exec 2> >(colour_errors >&2) run_and_prefix_stderr() { $@ 2> >(perl -pne "s/^(?!\s*$)/$(print_red $1:) /" >&2) } generate_lookup_paths() { echo $PATH | perl -pne "s/(?=:|$)/\/$1\1/g;s/:/\n/g" } report_missing_from_system() { local result local unformatted echo Error: $1 is not installed on system! >&2 echo 'Possible install candidate(s):' >&2 if [[ "$OS" == "rhel" ]]; then run_and_prefix_stderr dnf provides $(generate_lookup_paths $1) | perl -ne 'print $_ =~ s/^(.+?)-[\d.]+-\d+\.el.*\n/\1: /r if $_ =~ /-[\d.]+-\d+\.el.*/; print $_ =~ s/^Filename\s*:\s*(.*)\n/\1\n/r if $_ =~ /^Filename/' | perl -pne "s/(^[^:]+|$1)/$(print_purple '\\1')/g" | sort -u >&2 else # debian unformatted=$(printf "^%s$\n" $(generate_lookup_paths $1) | apt-file search -x -f - 2>/dev/null) result=$? [[ -n $unformatted ]] && echo $unformatted | perl -pne "s/(^[^:]+|$1)/$(print_purple '\\1')/g" >&2 [[ $result != '0' ]] && echo Error: No Matches found >&2 fi return 0 } OS=$(awk -F= '/^ID_LIKE/{print $2}' /etc/os-release | perl -pne 's/.*(rhel|debian).*/\1/') [[ "$OS" != "rhel" && "$OS" != "debian" ]] && echo Error: unsupported OS >&2 && exit 1 EXE_PATHS=() FAIL_FLAG=0 # iterate through each program name while read -r line; do [[ -z "$line" ]] && continue # get resolved path(s) (/bin and /usr/bin) path=( $(which -a $line) ) result=$? [[ $result != 0 ]] && report_missing_from_system $line >&2 && FAIL_FLAG=$result && continue # append path(s) to array EXE_PATHS+=( "${path[@]}" ) done [[ "${#EXE_PATHS[@]}" == "0" ]] && echo Error: no executables to query! >&2 && exit 1 # search for packages providing said programs, removing duplicates if [[ "$OS" == "rhel" ]]; then PACKAGES=$(run_and_prefix_stderr rpm -qf "${EXE_PATHS[@]}" --queryformat='%{NAME}\n' | sort -u) else PACKAGES=$(run_and_prefix_stderr dpkg-query -S --no-pager "${EXE_PATHS[@]}" 2> >(sed '/no path found matching pattern/d' >&2) | cut -d: -f1 | sort -u) fi [[ $FAIL_FLAG != 0 ]] && echo 'Error: some dependencies were not installed on this system. Some packages may be missing.' >&2 printf "%s\n" "${PACKAGES[@]}" echo Packages found: >&2 printf "%s\n" "${PACKAGES[@]}" >&2 exit $FAIL_FLAG