Detect if executable file is on user's PATH
(P)在一个基本的脚本中,我需要确定一个可执行的字母名称是什么。(p)
您也可以使用bash内置的
1 2 3 4 5 | help type cmd=ls [[ $(type -P"$cmd") ]] && echo"$cmd is in PATH" || { echo"$cmd is NOT in PATH" 1>&2; exit 1; } |
您可以使用
1 2 3 4 | path_to_executable=$(which name_of_executable) if [ -x"$path_to_executable" ] ; then echo"It's here: $path_to_executable" fi |
您可以使用与posix兼容的
1 2 3 | if [ -x"$(command -v"$cmd")" ]; then echo"$cmd is in \$PATH" fi |
由于
在bash中,您还可以使用
1 2 3 | if type -P"$cmd" &>/dev/null; then echo"$cmd is in \$PATH" fi |
正如注释中已经提到的,避免使用
DR:
在
1 2 3 | function is_bin_in_path { builtin type -P"$1" &> /dev/null } |
1 2 | % is_bin_in_path ls && echo"in path" || echo"not in path" in path |
无需避免的解决方案
这不是一个简短的答案,因为解决方案必须正确处理:
- 功能
- 别名
- 内置命令
- 保留词
以纯
1 2 3 4 5 6 7 8 9 10 11 12 | $ 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 |
注意,是
1 2 3 | $ PATH=/bin $ builtin type which which is /bin/which |
这个答案说明了为什么要避免使用
Avoid
which . Not only is it an external process you're launching for doing very little (meaning builtins likehash ,type orcommand are way cheaper), you can also rely on the builtins to actually do what you want, while the effects of external commands can easily vary from system to system.Why care?
- Many operating systems have a
which that doesn't even set an exit status, meaning theif which foo won't even work there and will always report thatfoo exists, even if it doesn't (note that some POSIX shells appear to do this forhash too).- Many operating systems make
which do custom and evil stuff like change the output or even hook into the package manager.
在这种情况下,也要避免
我刚才引用的答案建议使用
在
1
2
3 -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
在
1
2 -p Do a path search for name even if it is an alias,
reserved word, shell function or builtin.
对于同时在
1 2 3 4 5 6 7 8 9 | # 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 } |
如果命令-v foo;那么foo;否则echo"foo不可用";fi
我们可以使用
1 2 3 | function is_executable() { which"$@" &> /dev/null } |
调用函数就像调用可执行文件一样。
由于函数没有用返回代码显式返回,因此当函数返回时,最新执行的可执行文件(在本例中为
然后我们可以使用这个函数有条件地做一些事情:
1 2 3 4 5 | if is_executable name_of_executable; then echo"name_of_executable was found" else echo"name_of_executable was NOT found" fi |
在这里,
或者,我们可以跳过定义函数,直接在
1 2 3 4 5 | if which name_of_executable &> /dev/null; then echo"name_of_executable was found" else echo"name_of_executable was NOT found" fi |
但是,我认为这会使代码的可读性稍差。
使用
1 | $ which myprogram |