我正在编写我的第一个shell脚本。在我的脚本中,我想检查是否存在某个命令,如果不存在,则安装可执行文件。如何检查此命令是否存在?
if #check that foobar command doesnt exist
then
#now install foobar
fi
答案 0 :(得分:215)
一般情况下,这取决于您的shell,但如果您使用bash,zsh,ksh或sh(由破折号提供),则以下内容应该有效:
if ! type "$foobar_command_name" > /dev/null; then
# install foobar here
fi
对于真正的安装脚本,如果存在别名type
,您可能希望确保foobar
无法成功返回。在bash中你可以这样做:
if ! foobar_loc="$(type -p "$foobar_command_name")" || [[ -z $foobar_loc ]]; then
# install foobar here
fi
答案 1 :(得分:32)
尝试使用type
:
type foobar
例如:
$ type ls
ls is aliased to `ls --color=auto'
$ type foobar
-bash: type: foobar: not found
这优于which
,原因如下:
1)默认的which
实现仅支持显示所有选项的-a
选项,因此您必须找到支持别名的替代版本
2)type会告诉你你正在看什么(无论是bash函数还是别名或正确的二进制文件)。
3)类型不需要子进程
4)类型不能被二进制文件掩盖(例如,在linux框中,如果你创建一个名为which
的程序,它出现在真实which
之前的路径中,那么事情就会受到粉丝的影响。另一方面,type
是一个内置的shell [是的,下属无意中曾经这样做过一次]
答案 2 :(得分:21)
五种方式,4种用于bash,1种用于zsh:
type foobar &> /dev/null
hash foobar &> /dev/null
command -v foobar &> /dev/null
which foobar &> /dev/null
(( $+commands[foobar] ))
(仅限zsh)您可以将其中任何一个放入if
子句中。根据我的测试(https://www.topbug.net/blog/2016/10/11/speed-test-check-the-existence-of-a-command-in-bash-and-zsh/),建议在bash中使用第一种和第三种方法,并且在速度方面建议在zsh中使用第五种方法。
答案 3 :(得分:16)
Check if a program exists from a Bash script非常清楚。在任何shell脚本中,如果可以运行command -v $command_name
,最好运行$command_name
进行测试。在bash中,你可以使用hash $command_name
,它也可以使用任何路径查找的结果,或type -P $binary_name
,如果你只想查看二进制文件(不是函数等)。
答案 4 :(得分:13)
问题没有指定shell,因此对于使用 fish (friendly interactive shell)的人:
if command --search foo >/dev/null do
echo exists
else
echo does not exist
end
要获得基本的POSIX兼容性,请使用-v
标志,该标志是--search
或-s
的别名。
答案 5 :(得分:1)
which <cmd>
如果适用于您的案例,也会看到options which
supports的别名。
实施例
$ 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中。通常,为了检查某些东西是否“已安装”,可以使用与OS相关的安装相关命令。例如。 RHEL rpm -qa | grep -i "foobar"
。
答案 6 :(得分:0)
我在安装脚本中使用的函数正好用于此
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
答案 7 :(得分:0)
在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
中找不到命令,则返回非零值。