如何在别名命令上使用“哪个”?


76

像大多数用户一样,我设置了一堆别名来为常用程序提供默认的标志集。例如,

alias vim='vim -X'
alias grep='grep -E'
alias ls='ls -G'

问题是,如果我想使用which上看到我的vim/ grep/ ls/等从,别名的方式来获得:

$ which vim
vim: aliased to vim -X

这是有用的输出,但是在这种情况下不是我想要的;我知道vim是别名,vim -X但我想知道 vim的来源。

除了临时取消定义别名(以便我可以which在上面使用)之外,是否有一种简单的方法来which“解开”别名并在其上运行?

编辑:似乎which是一个shell内置的,在不同的shell上具有不同的行为。在Bash中,SiegeX对--skip-alias旗帜的建议起作用了。但是,我在Zsh上。那里是否存在类似的东西?


在zsh中,如果你想知道哪里是vim从何而来,你会使用where vim
Matija NALIS

Answers:


105

which实际上,这样做是一种糟糕的方法,因为它会根据您的环境$SHELL以及Shell使用的启动文件(它认为)进行猜测;它不仅有时会猜错,而且通常不能说出其行为有所不同。(例如,which在我的Ubuntu 10.10上,--skip-alias如@SiegeX所述,我无法理解。) type使用当前的shell环境而不是在配置文件中进行戳戳,并且可以被告知忽略该环境的某些部分,因此它向您显示了实际情况发生,而不是在重建默认外壳程序时发生的情况。

在这种情况下,type -P将绕过任何别名或函数:

$ type -P vim
/usr/bin/vim

您还可以要求它一次剥离所有层,并向您展示会发现什么:

$ type -a vim
vim is aliased to `vim -X'
vim is /usr/bin/vim

(在评论中对此进行扩展:)

问题which在于它通常是外部程序,而不是内置的Shell,这意味着它看不到您的别名或函数,必须尝试从Shell的启动/配置文件中重建它们。(如果它是内置的外壳,则zsh不是bash,但显然不是,它更有可能使用外壳的环境并做正确的事。)

type是符合POSIX的命令,必须像内置命令一样运行(也就是说,它必须使用从本地别名和函数中调用的外壳环境),因此通常内置命令。

通常不会在csh/中找到它tcsh,尽管在大多数现代版本中,它们which是内置的shell并执行正确的操作;有时是内置的what,有时根本没有从csh/ 查看当前shell环境的好方法tcsh


6
谢谢!这对添加到我的技巧包中非常有用。我尤其喜欢这样,type -a似乎会返回您的所有实例$PATH,而不仅仅是第一个。我想我会别名whichtype:)
Adrian Petrescu

2
// @ geekosaur:谢谢。如果这type是POSIX标准的一部分,那么这就是要走的路。为了回答我的问题,在zsh上(在Debian上)也可以使用type。为什么不发行摆脱whatwhich,如果他们没有标准,没有多余的功能?
Faheem Mitha

1
不,甚至不是远程的。
geekosaur 2011年

1
@Faheem:关于文档,我将从info bash 'Bash builtins'Linux 开始,尽管您也可以从zsh参考手册中获得它。更正式地说,是pubs.opengroup.org/onlinepubs/009695399/utilities/type.html(我注意到实际上不是spec -P-a,甚至-p不是的原始形式-P,但确实要求它使用当前的shell环境)。
geekosaur 2011年

2
type -pzsh和bash之间的行为有所不同。type -P在zsh中根本不存在。
kojiro

15

bash

type -P vim

zsh

type -p vim

同时:

/usr/bin/which vim

要么:

( unalias vim; type vim )

2
最后一个很酷。我们可以使用别名来执行此操作。:)
balki 2011年

在redhat上的bash中,我必须使用-P类型,如果我想要正确的答案,则不能使用-P类型。无需考虑别名或功能。

埃瓦尔博士,哪个“哪个”?哪个红帽?
Mikel

@Mikel RH7.4。GNU v2.20。

4

在zsh中which是内置函数,此命令报告:

$ whence -w which
which: builtin

要执行外部命令(在任何shell中)which,请使用完整路径

$ /bin/which ls; echo $?
/bin/ls
0

因此ls找到了该命令(退出值为0),并且位于/bin/ls

内部zsh; 一种搜索外部命令的方法(除上述方法外)是:

$ whence -p ls
/bin/ls

但是,这将无法解析嵌套的别名,例如:

$ alias dire='ls -l'

该命令将报告未dire找到命令。

$ whence -p dire; echo $?
1

有关解析嵌套别名(手动),请参见 Resolve nested aliases to their source commands


2

我的定义是这样的

alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

1

请尝试以下操作:

which --skip-alias vim

1
有趣!这适用于Bash,但不适用于Zsh(我真的不认为这将取决于Shell)。这使我意识到,which它实际上是一个内置的shell,而不是我所假设的常规Unix实用程序。因此,我应该编辑我的问题并指定Zsh。感谢您向我指出!
Adrian Petrescu

which不是内置的,至少不是在Debian上。它是一个shell脚本,是debianutils的一部分,因此可以在zsh上使用。但是,--skip-alias不是which在Debian上的选项。which周围有不同的漂浮物吗?这似乎不是标准命令。
Faheem Mitha

@Faheem Mitha:这是一个zsh内置函数。请参阅man zshbuiltins其中[-wpams]名称...等效于where -c。
Mikel

是的,对于Xubuntu来说bash,它不是内置的,没有--skip-alias选项。
polym 2014年

在CentOS(和RHEL?)6上,它是一个可执行文件,/usr/bin/which外加一个别名/etc/profile.d,使它可以处理别名但--skip-alias可以工作。结果which which显示了别名,但command which which显示了可执行文件!
dave_thompson_085

0

另一个选择是command which vim,它在zshbash

例如在我的Mac上:

LOLcalhost :: ~ % command which grep
/usr/local/bin/grep

足够公平。
Zee Alexander

0

两者的行为根据您的外壳类型typewhich有所不同。

在bash中,which存在一个命令PATH。它搜索您在中提供的命令PATH。Bash内置type -P(P为PATH)的行为与完全相同which

在ZSH中,which和和type均为内建函数,以及内建函数的部分功能whencewhich -p是你想要的。它强制进行路径搜索。(该-P选项不适用于typeZSH。)

whence [-vcwfpamsS] [-x num]名称...

-p

即使名称是别名,保留字,shell函数或内置名称,也要进行路径搜索。

ZSH手册中的更多内容。

哪个[-wpamsS] [-x num]名称...

等同于wherece -c。

要跳过builtin which和强制使用的命令which来自PATH于ZSH:

alias which="command which"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.