在bash脚本中,我需要确定名为foo
的可执行文件是否在PATH上。
答案 0 :(得分:35)
您还可以使用Bash内置type -P
:
help type
cmd=ls
[[ $(type -P "$cmd") ]] && echo "$cmd is in PATH" ||
{ echo "$cmd is NOT in PATH" 1>&2; exit 1; }
答案 1 :(得分:32)
您可以使用which
:
path_to_executable=$(which name_of_executable)
if [ -x "$path_to_executable" ] ; then
echo "It's here: $path_to_executable"
fi
答案 2 :(得分:4)
您可以使用与POSIX兼容的command
内置:
if [ -x "$(command -v "$cmd")" ]; then
echo "$cmd is in \$PATH"
fi
需要执行可执行检查,因为command -v
会检测函数和别名以及可执行文件。
在Bash中,您还可以type
使用-P
选项,这会强制进行PATH
搜索:
if type -P "$cmd" &>/dev/null; then
echo "$cmd is in \$PATH"
fi
正如评论中已经提到的那样,请避免使用which
,因为它需要启动外部流程,并且可能会在some cases中向您提供错误的输出。
答案 3 :(得分:3)
在bash
中:
function is_bin_in_path {
builtin type -P "$1" &> /dev/null
}
is_bin_in_path
的用法示例:
% is_bin_in_path ls && echo "in path" || echo "not in path"
in path
这不是一个简短的答案,因为解决方案必须正确处理:
示例为失败且答案为纯type
(请注意type
更改后的令牌):
$ alias foo=ls
$ type foo && echo "in path" || echo "not in path"
foo is aliased to `ls'
in path
$ type type && echo "in path" || echo "not in path"
type is a shell builtin
in path
$ type if && echo "in path" || echo "not in path"
if is a shell keyword
in path
请注意,bash
,which
不是内置的shell(位于zsh
中):
$ PATH=/bin
$ builtin type which
which is /bin/which
This answer说为什么避免使用which
:
避免使用
which
。它不仅是您为执行很少工作而启动的外部过程(意味着hash
,type
或command
之类的内置程序要便宜得多),您还可以依靠内置程序来实际执行做您想做的事,而外部命令的效果可能随系统而异。为什么要照顾?
- 许多操作系统的
which
甚至没有设置退出状态 ,这意味着if which foo
甚至无法在其中运行,并且会始终< / strong>报告foo
存在,即使不存在(请注意,有些POSIX shell似乎也为hash
做此操作)。- 许多操作系统使
which
进行自定义和恶意操作,例如更改输出甚至挂接到包管理器。
command -v
我刚刚引用的答案建议使用command -v
,但这不适用于当前的“ $PATH
中的可执行文件吗?”场景:它将完全按照我在上面的普通type
中说明的方式失败。
在bash
中,我们需要使用type -P
:
-P force a PATH search for each NAME, even if it is an alias, builtin, or function, and returns the name of the disk file that would be executed
在zsh
中,我们需要使用whence -p
:
-p Do a path search for name even if it is an alias, reserved word, shell function or builtin.
对于同时适用于{ba,z}sh
的版本:
# True if $1 is an executable in $PATH
# Works in both {ba,z}sh
function is_bin_in_path {
if [[ -n $ZSH_VERSION ]]; then
builtin whence -p "$1" &> /dev/null
else # bash:
builtin type -P "$1" &> /dev/null
fi
}
答案 4 :(得分:1)
如果命令-v foo;然后foo;否则回声&#34; foo不可用&#34; ;网络
答案 5 :(得分:0)
使用which
$ which myprogram
答案 6 :(得分:0)
我们可以使用which
定义一个检查可执行文件是否存在的函数:
function is_executable() {
which "$@" &> /dev/null
}
该函数的调用就像调用可执行文件一样。 "$@"
确保which
获得与该函数完全相同的参数。
&> /dev/null
确保将which
写入stdout或stderr的任何内容重定向到空设备(这是丢弃写入信息的特殊设备),而不是将其写入stdout或stderr通过功能。
由于该函数未明确返回返回代码,因此当它返回时,最新执行的可执行文件(在这种情况下为which
的退出代码)将是该函数的返回代码。如果which
能够找到该函数的参数指定的可执行文件,则将以指示成功的代码退出,否则将以指示失败的退出代码退出。此行为将由is_executable
自动复制。
然后我们可以使用该函数有条件地执行某些操作:
if is_executable name_of_executable; then
echo "name_of_executable was found"
else
echo "name_of_executable was NOT found"
fi
在这里,if
执行在它和then
之间编写的命令(在我们的情况下为is_executable name_of_executable
),并根据命令的返回代码选择要执行的分支。命令。
或者,我们可以跳过定义函数,而直接在which
语句中使用if
:
if which name_of_executable &> /dev/null; then
echo "name_of_executable was found"
else
echo "name_of_executable was NOT found"
fi
但是,我认为这会使代码的可读性稍差。