How to check if a program exists from a Bash scrip

2018-12-31 02:39发布

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's been stumping me.

标签: bash
30条回答
春风洒进眼中
2楼-- · 2018-12-31 03:09

Expanding on @lhunath's and @GregV's answers, here's the code for the people who want to easily put that check inside an if statement:

exists()
{
  command -v "$1" >/dev/null 2>&1
}

Here's how to use it:

if exists bash; then
  echo 'Bash exists!'
else
  echo 'Your system does not have Bash'
fi
查看更多
何处买醉
3楼-- · 2018-12-31 03:10

If you check for program existence, you are probably going to run it later anyway. Why not try to run it in the first place?

if foo --version >/dev/null 2>&1; then
    echo Found
else
    echo Not found
fi

It's a more trustworthy check that the program runs than merely looking at PATH directories and file permissions.

Plus you can get some useful result from your program, such as its version.

Of course the drawbacks are that some programs can be heavy to start and some don't have a --version option to immediately (and successfully) exit.

查看更多
深知你不懂我心
4楼-- · 2018-12-31 03:10

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 printf "OK\n"; else printf "missing\n"; fi
done

Sample output:

latex     OK
pandoc    missing

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

查看更多
梦醉为红颜
5楼-- · 2018-12-31 03:12

For those interested, none of the methodologies above work if you wish to detect an installed library. I imagine you are left either with physically checking the path (potentially for header files and such), or something like this (if you are on a Debian-based distro):

dpkg --status libdb-dev | grep -q not-installed

if [ $? -eq 0 ]; then
    apt-get install libdb-dev
fi

As you can see from the above, a "0" answer from the query means the package is not installed. This is a function of "grep" - a "0" means a match was found, a "1" means no match was found.

查看更多
姐姐魅力值爆表
6楼-- · 2018-12-31 03:13

I have a function defined in my .bashrc that makes this easier.

command_exists () {
    type "$1" &> /dev/null ;
}

Here's an example of how it's used (from my .bash_profile.)

if command_exists mvim ; then
    export VISUAL="mvim --nofork"
fi
查看更多
大哥的爱人
7楼-- · 2018-12-31 03:13

I'd say there's no portable and 100% reliable way due to dangling aliases. For example:

alias john='ls --color'
alias paul='george -F'
alias george='ls -h'
alias ringo=/

Of course only the last one is problematic (no offence to Ringo!) But all of them are valid aliases from the point of view of command -v.

In order to reject dangling ones like ringo, we have to parse the output of the shell built-in alias command and recurse into them (command -v is no superior to alias here.) There's no portable solution for it, and even a Bash-specific solution is rather tedious.

Note that solution like this will unconditionally reject alias ls='ls -F'

test() { command -v $1 | grep -qv alias }
查看更多
登录 后发表回答