..
为什么which无法定位到命令的位置?
先说结论:这是因为PATH里用了家目录缩写符号~
,而which应该是只按字符串静态匹配的,没有展开~
,所以找不到命令所在位置。
问题
最近在which
命令的时候发现无法打印出命令的位置,但是命令又确实存在,并且可以执行。实在百思不得其解!
所幸大概记得之前同事分享的type
跟command
这两个命令,临时用他们找到了命令所在位置。
> command -V helm
helm is /xxx/yyy/bin/helm
> type -a helm
helm is /xxx/yyy/bin/helm
然后echo了PATH,对比了一下命令所在路径与PATH环境变量,才发现问题是出在~
上。这里顺便实现了一个查看PATH的脚本:
#!/usr/bin/env node
const PATH = process.env.PATH;
PATH.split(':').forEach(item => console.log(item))
type与command详细介绍
Display the type of command the shell will execute.
type的作用是查看"命令"的类型,同时也能起到跟which一样的作用,查看命令所在位置。
# type显示echo是一个builtin命令
> type echo
echo is a shell builtin
# 如果命令是一个alias,则会说出它alias的内容。我的rm命令是一个alias
> type rm
rm is aliased to `trash'
# 如果命令是函数,则还会打印出函数体。这里省略下函数内容
> type eks
eks is a function
eks ()
{...
# -a 会列出所有查找到的路径结果。这里内容重复,是因为我的PATH配得太乱了,有重复。
> type -a openssl
openssl is /usr/bin/openssl
openssl is /Users/xxx/homebrew/bin/openssl
openssl is /usr/bin/openssl
openssl is /usr/bin/openssl
# -a 对alias也是有效的
> type -a rm
rm is aliased to `trash'
rm is /bin/rm
rm is /bin/rm
# -p 参数则表示那么多的openssl中,哪一个会被执行,类似which openssl。
> type -p openssl
/usr/bin/openssl
# 可能是因为会被执行的rm是一个alias,-p则没有打印出位置,
# 但也没有类似-a那样,打印出 rm is aliased to `trash'
> type -p rm
Command forces the shell to execute the program and ignore any functions, builtins and aliases with the same name.
command也能起到which命令的作用,但是它的主要作用是强制执行一个命令本身,忽略alias、functions、以及builtins。连builtins也忽略,我不太能理解。
# 试试忽略alias的情况,command <cmd>
> alias ls="echo 'hello world'"
> ls
hello world
> command ls
Applications Documents Movies Public ...
# -v 参数的作用跟type -p的作用类似
> command -v ls
alias ls='echo '\''hello world'\'''