How can I check if a program exists from a Bash script?

后端 未结 30 1959
有刺的猬
有刺的猬 2020-11-21 07:21

How would I validate that a program exists, in a way that will either return an error and exit, or continue with the script?

It seems like it should be easy, but it\

相关标签:
30条回答
  • 2020-11-21 08:03

    To use hash, as @lhunath suggests, in a Bash script:

    hash foo &> /dev/null
    if [ $? -eq 1 ]; then
        echo >&2 "foo not found."
    fi
    

    This script runs hash and then checks if the exit code of the most recent command, the value stored in $?, is equal to 1. If hash doesn't find foo, the exit code will be 1. If foo is present, the exit code will be 0.

    &> /dev/null redirects standard error and standard output from hash so that it doesn't appear onscreen and echo >&2 writes the message to standard error.

    0 讨论(0)
  • 2020-11-21 08:03

    Check for multiple dependencies and inform status to end users

    for cmd in latex pandoc; do
      printf '%-10s' "$cmd"
      if hash "$cmd" 2>/dev/null; then
        echo OK
      else
        echo missing
      fi
    done
    

    Sample output:

    latex     OK
    pandoc    missing
    

    Adjust the 10 to the maximum command length. It is not automatic, because I don't see a non-verbose POSIX way to do it: How can I align the columns of a space separated table in Bash?

    Check if some apt packages are installed with dpkg -s and install them otherwise.

    See: Check if an apt-get package is installed and then install it if it's not on Linux

    It was previously mentioned at: How can I check if a program exists from a Bash script?

    0 讨论(0)
  • 2020-11-21 08:03

    I had to check if Git was installed as part of deploying our CI server. My final Bash script was as follows (Ubuntu server):

    if ! builtin type -p git &>/dev/null; then
      sudo apt-get -y install git-core
    fi
    
    0 讨论(0)
  • 2020-11-21 08:04

    I agree with lhunath to discourage use of which, and his solution is perfectly valid for Bash users. However, to be more portable, command -v shall be used instead:

    $ command -v foo >/dev/null 2>&1 || { echo "I require foo but it's not installed.  Aborting." >&2; exit 1; }
    

    Command command is POSIX compliant. See here for its specification: command - execute a simple command

    Note: type is POSIX compliant, but type -P is not.

    0 讨论(0)
  • 2020-11-21 08:04

    To mimic Bash's type -P cmd, we can use the POSIX compliant env -i type cmd 1>/dev/null 2>&1.

    man env
    # "The option '-i' causes env to completely ignore the environment it inherits."
    # In other words, there are no aliases or functions to be looked up by the type command.
    
    ls() { echo 'Hello, world!'; }
    
    ls
    type ls
    env -i type ls
    
    cmd=ls
    cmd=lsx
    env -i type $cmd 1>/dev/null 2>&1 || { echo "$cmd not found"; exit 1; }
    
    0 讨论(0)
  • 2020-11-21 08:05

    The hash-variant has one pitfall: On the command line you can for example type in

    one_folder/process
    

    to have process executed. For this the parent folder of one_folder must be in $PATH. But when you try to hash this command, it will always succeed:

    hash one_folder/process; echo $? # will always output '0'
    
    0 讨论(0)
提交回复
热议问题