我认为大多数人都熟悉该which
命令,并且我经常使用它。我刚刚遇到了一种情况,我不仅好奇哪个命令在我的路径中第一个,而且好奇有多少个命令以及在哪里全部我所有路径中的命令都是。我尝试了哪个手册页(打字man which
让我笑),但没有看到任何东西。
答案1
在某些系统上,which -a
显示所有匹配项。如果您的 shell 是 bash 或 zsh1,您可以使用type
:type foo
显示第一个匹配项并type -a foo
显示所有匹配项。这三个命令type
,which
和whence
做的事情大多相同; shell 和操作系统之间的区别在于可用性、选项以及它们所报告的具体内容。type
始终可用,并显示所有可能的类似命令的名称(别名、关键字、shell 内置命令、函数和外部命令)。
显示所有匹配的唯一完全可移植的方法是解析$PATH
自己。这是执行此操作的 shell 脚本。如果将其设为 shell 函数,请确保将函数体括在括号中(以便更改为IFS
和set -f
不会转义该函数),然后更改exit
为return
.
#!/bin/sh
set -f # disable globbing
IFS=: # break words at : only
not_found=1
for d in $PATH; do
if [ -f "$d/$x" ] && [ -x "$d/$x" ]; then
printf '%s\n' "$d/$x"
not_found=0
fi
done
exit $not_found
或 ksh 93,根据文档,尽管 ksh 93s+ 2008-01-31 仅在我尝试时打印第一个匹配项 。
答案2
--all 或 -a 标志将显示路径中的所有匹配项和别名(至少在 Fedora、Ubuntu 和 CentOS 上):
which -a which
在 AIX 和 Solaris 上,这将使您接近:
echo "$PATH" | sed -e 's/:/ /g' | \
while read -r p; do find "$p" -type f -name "which"; done
答案3
如果您没有which
支持-a
或whence
可用,请自行推出:
#!/bin/sh -f
IFS=":"
for PART in $PATH
do
if test -x "$PART/$1"
then
echo $PART/$1
fi
done
答案4
ksh 和 zsh 内置了“whence”作为 shell。 whence -a
在 zsh 下做你想做的事:
7:27AM 7 % whence -a cat
/usr/bin/cat
/bin/cat
/usr/bin/cat
/bin/cat
我必须清理 zsh 中的 PATH,其中有很多重复项。whence -a
在 ksh 下的工作方式有所不同:
$ whence -a cat
cat is a tracked alias for /usr/bin/cat
我不得不说,这似乎也是一种潜在有用的行为。