Como usar `what` em um comando com alias?

76

Como a maioria dos usuários, tenho vários aliases configurados para fornecer um conjunto padrão de sinalizadores para programas usados ​​com freqüência. Por exemplo,

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

O problema é que, se eu quiser usar whichpara ver de onde vem meu vim/ grep/ ls/ etc, o alias fica no caminho:

$ which vim
vim: aliased to vim -X

Esta é uma saída útil, mas não é o que estou procurando neste caso; Eu sei que vimé um alias, vim -Xmas quero saber de onde isso vim vem.

Exceto temporariamente a não definição do alias, apenas para que eu possa usá which-lo, existe uma maneira fácil de which'desembrulhar' o alias e executar isso sozinho?

Edit: Parece que whiché um shell-builtin com comportamentos diferentes em diferentes conchas. No Bash, a sugestão da --skip-aliasbandeira do SiegeX funciona; no entanto, estou no Zsh. Existe algo semelhante lá?

Adrian Petrescu
fonte
no zsh, se você quiser saber de onde isso vimvem , você usaria #where vim
Matija Nalis

Respostas:

105

whiché realmente uma maneira ruim de fazer coisas assim, pois faz suposições sobre o seu ambiente com base nos $SHELLarquivos de inicialização (que ele acha) que o shell usa; às vezes, não apenas parece errado, mas você geralmente não pode dizer para se comportar de maneira diferente. ( whichno meu Ubuntu 10.10 não entende --skip-aliascomo mencionado por @SiegeX, por exemplo.) typeusa o ambiente de shell atual em vez de cutucar seus arquivos de configuração e pode ser instruído a ignorar partes desse ambiente, mostrando o que realmente acontecer em vez do que aconteceria em uma reconstrução do seu shell padrão.

Nesse caso, type -Pignorará quaisquer aliases ou funções:

$ type -P vim
/usr/bin/vim

Você também pode pedir para remover todas as camadas, uma de cada vez, e mostrar o que seria encontrado:

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

(Expandindo isso a partir dos comentários :)

O problema whiché que geralmente é um programa externo em vez de um shell embutido, o que significa que ele não pode ver seus apelidos ou funções e precisa reconstruí-los a partir dos arquivos de inicialização / configuração do shell. (Se é um shell embutido, como está, zshmas aparentemente não bashé, é mais provável que você use o ambiente do shell e faça a coisa certa.)

typeé um comando compatível com POSIX que deve se comportar como se fosse um built-in (ou seja, ele deve usar o ambiente do shell para o qual é invocado, incluindo aliases e funções locais); portanto, geralmente é um built-in.

Geralmente não é encontrado em csh/ tcsh, embora na maioria das versões modernas whichseja um shell embutido e faça a coisa certa; às vezes o built-in é what, e às vezes não há uma boa maneira de ver o ambiente atual do shell de csh/ tcshpara.

geekosaur
fonte
6
Obrigado! Isso é algo muito útil para adicionar à minha bolsa de truques. Eu particularmente gosto que type -aparece retornar todas as instâncias no seu $PATH, não apenas a primeira. Acho que vou apelido whichpara type:)
Adrian Petrescu
2
@ geekosaur: Obrigado. Se typefaz parte do padrão POSIX, esse é o caminho a seguir. Para responder minha pergunta, digite também funciona no zsh (no Debian). Por que as distribuições não se livram whate whichse não são padronizadas e não têm funcionalidade extra?
Faheem Mitha
1
Não, nem remotamente.
Geekosaur
1
@ Faaem: re documentação, eu começaria info bash 'Bash builtins'no Linux, embora você também possa obtê-lo no zshmanual de referência. Mais oficialmente, pubs.opengroup.org/onlinepubs/009695399/utilities/type.html (o que eu noto que na verdade não especifica -Pou -a, ou mesmo -pqual era a forma original -P, mas exige que ele use o ambiente de shell atual).
Geekosaur
2
type -pse comporta de maneira diferente entre zsh e bash. type -Pnão existe no zsh.
kojiro
15

Em bash:

type -P vim

Em zsh:

type -p vim

Em ambos:

/usr/bin/which vim

Ou:

( unalias vim; type vim )
Mikel
fonte
2
O último é legal. Podemos ter um alias para fazer isso. :)
balki
No bash no redhat eu tenho que usar o tipo -P, e não qual, se eu quiser a resposta correta. Nenhum alias ou função está em causa.
Dr. Eval, qual "qual"? Qual Red Hat?
Mikel
@Mikel RH7.4. GNU que v2.20.
4

No zsh whiché um builtin como este comando relata:

$ whence -w which
which: builtin

Para executar o comando externo (em qualquer shell) which, use o Caminho completo :

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

portanto, o comando lsfoi encontrado (um valor de saída 0) e está localizado em /bin/ls.

Dentro zsh; Uma maneira (ao lado da acima) de procurar comandos externos é:

$ whence -p ls
/bin/ls

No entanto, isso não resolverá aliases aninhados como:

$ alias dire='ls -l'

O comando relatará que nenhum direcomando foi encontrado.

$ whence -p dire; echo $?
1

Para resolver aliases aninhados (manualmente), consulte Resolve nested aliases to their source commands

HalosGhost
fonte
2

Mina definida como tal

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

Tente o seguinte:

which --skip-alias vim
SiegeX
fonte
1
Interessante! Isso funciona no Bash, mas não no Zsh (eu realmente não achei que isso fosse dependente do shell). Isso me fez perceber que, whichna verdade, é um shell embutido e não um utilitário Unix comum, como eu havia assumido. Então, eu devo editar minha pergunta e especificar Zsh. Obrigado por apontar isso para mim!
Adrian Petrescu
whichnão é embutido, pelo menos não no Debian. É um script de shell e parte do debianutils, então funciona no zsh. No entanto, --skip-aliasnão é uma opção whichno Debian. Existem diferentes variedades de whichflutuação? Isso não parece ser um comando padronizado.
Faheem Mitha 02/04
@ Faaem Mitha: É um zsh embutido. Veja man zshbuiltins. cujo nome [-wpams] ... Equivale a de onde -c.
Mikel
Sim, no Xubuntu bash, ele não é um built-in e não tem a --skip-aliasopção.
polym 31/07
No CentOS (e RHEL?) 6, é um executável /usr/bin/whichmais um alias /etc/profile.dque permite lidar com aliases, mas --skip-aliasfunciona. Como resultado, which whichmostra o alias, mas command which whichmostra o executável!
Dave_thompson_085
0

Outra alternativa é command which vim, que funciona da mesma maneira em ambos zshebash

Por exemplo, no meu mac:

LOLcalhost :: ~ % command which grep
/usr/local/bin/grep
Zee Alexander
fonte
Ah, bastante.
Zee Alexander
0

Ambos typee whichse comportam de maneira diferente de acordo com o seu tipo de shell.

No bash, whichexiste um comando no PATH. Ele pesquisa o comando que você fornece PATH. O Bash builtin type -P(P para PATH) se comporta exatamente como which.

No ZSH, ambos são whiche typesão funções integradas e parciais whence. which -pé o que você quer. Força uma pesquisa de caminho. (a -Popção não está disponível para typeZSH.)

de onde [-vcwfpamsS] [-x num] nome ...

-p

Faça uma busca de caminho pelo nome, mesmo que seja um alias, palavra reservada, função de shell ou interno.

Mais do manual ZSH.

qual nome [-wpamsS] [-x num] ...

Equivalente a de onde -c.

Para pular builtin whiche forçar comando uso whichde PATHem ZSH:

alias which="command which"
Simba
fonte