6

I'm trying to write a simple bash wrapper which abstracts yum and apt-get. Basically so we can do something like universal-install curl Here is what I have so far:

# universal-install
package=$1
apt=`command -v apt-get`
yum=`command -v yum`

if [ -n "$apt" ]; then
    apt-get update
    apt-get -y install $package
elif [ -n "$yum" ]; then
    yum -y install $package
else
    echo "Err: no path to apt-get or yum" >&2;
    exit 1;
fi

Are there any errors or improvements/optimizations that can be made?

Justin
  • 34,956
  • 68
  • 168
  • 266
  • Potential issue that jumps right out at me is that distributions name all their packages differently. A Debian `apt-get package` is very likely not to have the same name as a Redhat `yum install package` – Michael Berkowski Jan 29 '14 at 02:53
  • Yah, let's ignore package name differences. Not something that can be dealt with automatically that I know of. What be really cool if there was a service (api) that returned package names for most common distros. – Justin Jan 29 '14 at 02:55

4 Answers4

5

Take a look at how pacapt detects the OS:

# Detect package type from /etc/issue
_found_arch() {
  local _ostype="$1"
  shift
  grep -qis "$*" /etc/issue && _OSTYPE="$_ostype"
}

# Detect package type
_OSTYPE_detect() {
  _found_arch PACMAN "Arch Linux" && return
  _found_arch DPKG   "Debian GNU/Linux" && return
  _found_arch DPKG   "Ubuntu" && return
  _found_arch YUM    "CentOS" && return
  _found_arch YUM    "Red Hat" && return
  _found_arch YUM    "Fedora" && return
  _found_arch ZYPPER "SUSE" && return

  [[ -z "$_OSTYPE" ]] || return

  # See also https://github.com/icy/pacapt/pull/22
  # Please not that $OSTYPE (which is `linux-gnu` on Linux system)
  # is not our $_OSTYPE. The choice is not very good because
  # a typo can just break the logic of the program.
  if [[ "$OSTYPE" != "darwin"* ]]; then
    _error "Can't detect OS type from /etc/issue. Running fallback method."
  fi
  [[ -x "/usr/bin/pacman" ]]           && _OSTYPE="PACMAN" && return
  [[ -x "/usr/bin/apt-get" ]]          && _OSTYPE="DPKG" && return
  [[ -x "/usr/bin/yum" ]]              && _OSTYPE="YUM" && return
  [[ -x "/opt/local/bin/port" ]]       && _OSTYPE="MACPORTS" && return
  command -v brew >/dev/null           && _OSTYPE="HOMEBREW" && return
  [[ -x "/usr/bin/emerge" ]]           && _OSTYPE="PORTAGE" && return
  [[ -x "/usr/bin/zypper" ]]           && _OSTYPE="ZYPPER" && return
  if [[ -z "$_OSTYPE" ]]; then
    _error "No supported package manager installed on system"
    _error "(supported: apt, homebrew, pacman, portage, yum)"
    exit 1
  fi
}

As you can see it first checks /etc/issue, then failing that the script looks for the associated executable file for each package manager.

But heck, why not just use pacapt, instead of rolling your own?

Michael Kropat
  • 12,704
  • 9
  • 64
  • 85
1

If you're going to do this, why require the user to tell the script which tool to use?

#!/bin/bash
# Find our package manager
if VERB="$( which apt-get )" 2> /dev/null; then
   echo "Debian-based"
elif VERB="$( which yum )" 2> /dev/null; then
   echo "Modern Red Hat-based"
elif VERB="$( which portage )" 2> /dev/null; then
   echo "Gentoo-based"
elif VERB="$( which pacman )" 2> /dev/null; then
   echo "Arch-based"
else
   echo "I have no idea what I'm doing." >&2
   exit 1
fi
if [[ 1 -ne $# ]]; then
   echo "Syntax: $0 PACKAGE"
   exit 1
fi
$VERB "$1"
exit $?

Slightly better would to to look at /etc/issue to see what your distribution is and behave accordingly.

DopeGhoti
  • 727
  • 6
  • 13
  • ? He's not requiring the user to tell which tool to use anywhere in his script. Also don't use `which` – Reinstate Monica Please Jan 29 '14 at 04:07
  • 1
    Is there something amiss with `which` with which I should be aware? Inquiring minds want to know. – DopeGhoti Jan 29 '14 at 06:29
  • 1
    Yes, don't use `which` to check if a command exists, here is why: http://stackoverflow.com/questions/592620/how-to-check-if-a-program-exists-from-a-bash-script – Justin Jan 29 '14 at 06:40
1

I was looking for a one-liner to install a package and couldn't find any so this was my final version:

if [ "" == "`which unzip`" ]; then echo "Unzip Not Found"; if [ -n "`which apt-get`" ]; then apt-get -y install unzip ; elif [ -n "`which yum`" ]; then yum -y install unzip ; fi ; fi

It's specific for the unzip package, but can be altered to any other package that is available on apt-get/yum.

Hope this will help someone :)

Dekel
  • 53,749
  • 8
  • 76
  • 105
1
    #!/bin/bash
    # file: src/bash/aspark-starter/install-prerequisites-for-aspark-starter.sh
    # caveat package names are for Ubuntu !!!
    set -eu -o pipefail # fail on error , debug all lines

    # run as root
    [ "${USER:-}" = "root" ] || exec sudo "$0" "$@"

    echo "=== $BASH_SOURCE on $(hostname -f) at $(date)" >&2


    echo installing the must-have pre-requisites
    while read -r p ; do
        if [ "" == "`which $p`" ];
        then echo "$p Not Found";
            if [ -n "`which apt-get`" ];
            then apt-get install -y $p ;
            elif [ -n "`which yum`" ];
            then yum -y install $p ;
            fi ;
        fi
    done < <(cat << "EOF"
        perl
        zip unzip
        exuberant-ctags
        mutt
        libxml-atom-perl
        postgresql-9.6
        libdbd-pgsql
        curl
        wget
        libwww-curl-perl
    EOF
    )

    echo installing the nice-to-have pre-requisites
    echo you have 5 seconds to proceed ...
    echo or
    echo hit Ctrl+C to quit
    echo -e "\n"
    sleep 6

    echo installing the nice to-have pre-requisites
    while read -r p ; do
        if [ "" == "`which $p`" ];
        then echo "$p Not Found";
            if [ -n "`which apt-get`" ];
            then apt-get install -y $p ;
            elif [ -n "`which yum`" ];
            then yum -y install $p ;
            fi ;
        fi
    done < <(cat << "EOF"
        tig
    EOF
    )
Yordan Georgiev
  • 4,006
  • 1
  • 43
  • 47