我正在编写我的第一个shell脚本。在我的脚本中,我想检查某个命令是否存在,如果不存在,安装可执行文件。如何检查该命令是否存在?
if # Check that foobar command doesnt exist
then
# Now install foobar
fi
我正在编写我的第一个shell脚本。在我的脚本中,我想检查某个命令是否存在,如果不存在,安装可执行文件。如何检查该命令是否存在?
if # Check that foobar command doesnt exist
then
# Now install foobar
fi
试着使用type:
type foobar
例如:
$ type ls
ls is aliased to `ls --color=auto'
$ type foobar
-bash: type: foobar: not found
这是更可取的,有几个原因:
The default which implementations only support the -a option that shows all options, so you have to find an alternative version to support aliases type will tell you exactly what you are looking at (be it a Bash function or an alias or a proper binary). type doesn't require a subprocess type cannot be masked by a binary (for example, on a Linux box, if you create a program called which which appears in path before the real which, things hit the fan. type, on the other hand, is a shell built-in (yes, a subordinate inadvertently did this once).
而< cmd >
如果适用于您的情况,还请参阅支持别名的选项。
例子
$ which foobar
which: no foobar in (/usr/local/bin:/usr/bin:/cygdrive/c/Program Files (x86)/PC Connectivity Solution:/cygdrive/c/Windows/system32/System32/WindowsPowerShell/v1.0:/cygdrive/d/Program Files (x86)/Graphviz 2.28/bin:/cygdrive/d/Program Files (x86)/GNU/GnuPG
$ if [ $? -eq 0 ]; then echo "foobar is found in PATH"; else echo "foobar is NOT found in PATH, of course it does not mean it is not installed."; fi
foobar is NOT found in PATH, of course it does not mean it is not installed.
$
PS:注意不是所有安装的东西都在PATH中。通常,为了检查某些东西是否“安装”,人们会使用与操作系统相关的安装相关命令。例如:rpm -qa | grep -i "foobar" for RHEL。
一般来说,这取决于你的shell,但如果你使用bash, zsh, ksh或sh(由dash提供),下面应该工作:
if ! type "$foobar_command_name" > /dev/null; then
# install foobar here
fi
对于实际的安装脚本,您可能希望确保在存在别名foobar的情况下,该类型不会成功返回。在bash中,你可以这样做:
if ! foobar_loc="$(type -p "$foobar_command_name")" || [[ -z $foobar_loc ]]; then
# install foobar here
fi
检查Bash脚本中是否存在一个程序,这很好地涵盖了这一点。在任何shell脚本中,您最好运行命令-v $command_name来测试$command_name是否可以运行。在bash中,您可以使用hash $command_name,它也会对任何路径查找的结果进行散列,或者如果您只想查看二进制文件(而不是函数等),则键入-P $binary_name。
这个问题没有指定shell,所以对于那些使用fish(友好的交互式shell)的人:
if command -v foo > /dev/null
echo exists
else
echo does not exist
end
为了基本的POSIX兼容性,我们使用-v标志,它是——search或-s的别名。
5种方法,4个用于bash, 1个用于zsh:
类型foobar &> /dev/null 哈希foobar和> /dev/null 命令-v foobar和> /dev/null 哪个foobar &> /dev/null ($+突击队[foobar]) (zsh only)
你可以把它们中的任何一个放到你的if子句中。根据我的测试(https://www.topbug.net/blog/2016/10/11/speed-test-check-the-existence-of-a-command-in-bash-and-zsh/),就速度而言,bash中推荐第1和第3种方法,zsh中推荐第5种方法。
我在安装脚本中为此制作的函数
function assertInstalled() {
for var in "$@"; do
if ! which $var &> /dev/null; then
echo "Install $var!"
exit 1
fi
done
}
示例调用:
assertInstalled zsh vim wget python pip git cmake fc-cache
在bash和zsh中都可以工作的函数:
# Return the first pathname in $PATH for name in $1
function cmd_path () {
if [[ $ZSH_VERSION ]]; then
whence -cp "$1" 2> /dev/null
else # bash
type -P "$1" # No output if not in $PATH
fi
}
如果在$PATH中没有找到该命令,则返回非零。