Skip to content

Instantly share code, notes, and snippets.

@indifferentcats
Created June 21, 2023 15:26
Show Gist options
  • Save indifferentcats/62f874f77bf44a482a1faabda00dd043 to your computer and use it in GitHub Desktop.
Save indifferentcats/62f874f77bf44a482a1faabda00dd043 to your computer and use it in GitHub Desktop.
Linux script to auto-install packages for missing shared objects in binaries, typically ones downloaded from the Internet. This is a blind way to find and fix problems like those from chrome/chromedriver when it exits with code 127.
#!/bin/bash
my_uid=$(id -u)
if [ $my_uid -ne 0 ]; then
echo "WARNING: running as non-root. May not be able to install packages."
fi
HAS_APT=$(command -v apt)
HAS_DNF=$(command -v dnf)
HAS_YUM=$(command -v yum)
missing_packages_file=${MISSING_PACKAGES_FILE:-/tmp/list_of_missing_packages.txt}
function main() {
if [ -n "$HAS_APT" ]; then
echo "INFO: Found a debian-based distribution. Using apt-file."
fix_debian "$@"
elif [ -n "$HAS_DNF" ]; then
echo "INFO: Found an RPM-based distribution. Using dnf."
echo "WARNING: Finding packages with DNF is not yet supported."
exit 2
elif [ -n "$HAS_YUM" ]; then
echo "INFO: Found an RPM-based distribution. Using yum."
fix_rpm_yum "$@"
else
echo "WARNING: No package manager found. Automatic fixing not supported."
exit 1
fi
}
function fix_debian() {
apt_update
install_apt_file
libs=$(get_all_missing_libs "$@")
if [ -z "$libs" ]; then
echo "INFO: All dependant libraries found. No action."
return 0
fi
echo "INFO: Found $(wc -l <<<"$libs") missing libraries"
echo "INFO: Missing libs:" $libs
packages=$(get_missing_deb $libs)
echo "INFO: Found $(wc -l <<<"$packages") missing packages"
if [ -n "$packages" ]; then
echo "INFO: Installing missing packages:" $packages
echo "$packages" >> $missing_packages_file
install_missing_deb $packages
fi
if [ -z "$packages" ] && [ -n "$libs" ]; then
echo "ERROR: The binaries are missing .so files, but no install packages could be found."
exit 1
fi
uninstall_apt_file
apt_clean
echo "INFO: Checking our work"
libs=$(get_all_missing_libs "$@")
if [ -n "$libs" ]; then
echo "FAIL: The following libraries still did not get installed: $libs"
exit 2
fi
echo "INFO: Success. All libraries were found for the executable(s): $@"
}
function fix_dnf() {
:
}
function fix_rpm_yum() {
libs="$(get_all_missing_libs "$@")"
if [ -z "$libs" ]; then
echo "INFO: All dependant libraries found. No action."
return 0
fi
echo "INFO: Found $(wc -l <<<"$libs") missing libraries"
echo "INFO: Missing libs:" $libs
yum_install yum-utils
packages="$(get_missing_yum $libs | sed -e '/^[ ]*$/d')"
echo "INFO: Found $(echo "$packages" | wc -l ) missing packages"
if [ -n "$packages" ]; then
echo "INFO: Installing missing packages:" $packages
echo "$packages" >> $missing_packages_file
yum_install $packages
fi
if [ -z "$packages" ] && [ -n "$libs" ]; then
echo "ERROR: The binaries are missing .so files, but no install packages could be found."
exit 1
fi
yum_remove yum-utils
yum_clean
echo "INFO: Checking our work"
libs=$(get_all_missing_libs "$@")
if [ -n "$libs" ]; then
echo "FAIL: The following libraries still did not get installed: $libs"
exit 2
fi
echo "INFO: Success. All libraries were found for the executable(s): $@"
}
function get_all_missing_libs() {
for bin in "$@"; do
if [ -e "$bin" ] && [ -x "$bin" ]; then
/bin/ldd "$bin" | grep not\ found | sed -e 's/^[ \t]*//; s/ =>.*.//'
else
echo "ERROR: $bin does not exist or is not executable. Do not pass links." 1>&2
return
fi
done | sort | uniq
}
function get_missing_deb() {
# some packages don't work well with others.
# liboss4-salsa-asound2 conflicts with libasound2
debs_to_ignore="(liboss4-salsa-asound2)"
for lib in "$@"; do
apt-file search $lib 2>/dev/null | cut -f1 -d:
done | sort | uniq | grep -E -v -e '(firefox|thunderbird|chrome|chromium|-dev|-debug)' |\
grep -E -v -e "$debs_to_ignore"
}
function get_missing_yum() {
for lib in "$@"; do
repoquery --whatprovides $lib --qf '%{NAME}' | head -1
done | sort | uniq
}
function install_missing_deb() {
echo "INFO: installing packages " "$@"
show_on_error apt-get install -y "$@";
}
function apt_update() { show_on_error apt-get update; }
function install_apt_file() {
show_on_error apt-get install -y apt-file;
show_on_error apt-file update;
}
function uninstall_apt_file() { show_on_error apt-get remove -y apt-file; }
function apt_clean() { show_on_error apt-get clean; }
function yum_install() { show_on_error yum install -y "$@"; }
function yum_remove() { show_on_error yum remove -y "$@"; }
function yum_clean() { show_on_error yum clean all; show_on_error rm -rf /var/cache/yum; }
function show_on_error() {
output=$("$@" 2>&1)
err=$?
if [ $err -ne 0 ]; then echo "$output"; fi
return $err
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment