Jak korzystać z „które” w aliasowanym poleceniu?

76

Podobnie jak większość użytkowników, mam skonfigurowanych kilka aliasów, które dają domyślny zestaw flag dla często używanych programów. Na przykład,

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

Problem polega na tym, że jeśli chcę użyć, whichaby zobaczyć, skąd pochodzi mój vim/ grep/ ls/ etc, alias przeszkadza:

$ which vim
vim: aliased to vim -X

Jest to użyteczne wyjście, ale nie to, czego szukam w tym przypadku; Wiem, że vimjest aliasem vim -X, ale chcę wiedzieć, gdzie to vim pochodzi.

Czy whichbrakuje mi tymczasowego usunięcia definicji aliasu, abym mógł z niego korzystać, czy jest prosty sposób na which„rozpakowanie” aliasu i uruchomienie się na nim?

Edycja: Wygląda na whichto, że jest to wbudowana powłoka o różnych zachowaniach w różnych powłokach. W Bash działa sugestia SiegeX dotycząca --skip-aliasflagi; jednak jestem na Zsh. Czy istnieje coś podobnego?

Adrian Petrescu
źródło
w Zsh, jeśli chcesz wiedzieć, skąd vimpochodzi , skorzystajwhere vim
Matija Nalis

Odpowiedzi:

105

whichjest w rzeczywistości złym sposobem na robienie takich rzeczy, ponieważ zgaduje o twoim środowisku na podstawie $SHELLplików startowych (tak myśli), których używa powłoka; czasami nie tylko zgaduje, że jest źle, ale ogólnie nie można powiedzieć, aby zachowywał się inaczej. ( whichna moim Ubuntu 10.10 nie rozumie, --skip-aliasjak wspomniano na przykład @SiegeX). typewykorzystuje bieżące środowisko powłoki zamiast szturchać plików konfiguracyjnych i może zostać poproszony o zignorowanie części tego środowiska, więc pokazuje ci, co faktycznie wydarzy się zamiast tego, co by się stało w rekonstrukcji domyślnej powłoki.

W takim przypadku type -Ppominie wszelkie aliasy lub funkcje:

$ type -P vim
/usr/bin/vim

Możesz również poprosić go o zerwanie wszystkich warstw, pojedynczo i pokazanie, co by znalazł:

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

(Rozszerzając to na podstawie komentarzy :)

Problem whichpolega na tym, że zwykle jest to program zewnętrzny zamiast wbudowanej powłoki, co oznacza, że ​​nie widzi twoich aliasów lub funkcji i musi spróbować je zrekonstruować z plików startowych / konfiguracyjnych powłoki. (Jeśli jest to wbudowana powłoka, tak jak jest, zshale najwyraźniej nie bashjest, bardziej prawdopodobne jest, że użyje środowiska powłoki i zrobi właściwą rzecz.)

typejest poleceniem zgodnym z POSIX, które musi zachowywać się tak, jakby było wbudowane (tzn. musi używać środowiska powłoki, do której jest wywoływane, w tym lokalnych aliasów i funkcji), więc zwykle jest to wbudowane.

Zazwyczaj nie można go znaleźć w csh/ tcsh, chociaż w większości współczesnych wersji whichjest on wbudowany w powłokę i działa poprawnie; czasami wbudowane jest whatzamiast tego, a czasem nie ma dobrego sposobu, aby zobaczyć środowisko bieżącego shella z csh/ tcshw ogóle.

geekozaur
źródło
6
Dzięki! Jest to coś bardzo przydatnego do dodania do mojej torby sztuczek. Szczególnie podoba mi się, że type -awydaje się , że zwracają wszystkie twoje wystąpienia $PATH, nie tylko pierwsze. Chyba będę alias whichdo type:)
Adrian Petrescu
2
@ geekosaur: Thanks. Jeśli typejest częścią standardu POSIX, to jest to właściwy sposób. Aby odpowiedzieć na moje pytanie, wpisz również działa na zsh (na Debianie). Dlaczego dystrybucje się nie pozbywają, whata whichjeśli nie są znormalizowane i nie mają dodatkowej funkcjonalności?
Faheem Mitha
1
Nie, nawet zdalnie.
geekozaur
1
@Faheem: ponowna dokumentacja, zacznę info bash 'Bash builtins'od Linuksa, chociaż można go również pobrać z zshpodręcznika. Bardziej oficjalnie, pubs.opengroup.org/onlinepubs/009695399/utilities/type.html (co zwrócić uwagę w rzeczywistości nie wg planu -Plub -a, lub nawet -pco było oryginalną formą -P, ale wymaga to, że korzystać z bieżącym środowisku powłoki).
geekozaur
2
type -pzachowuje się inaczej między zsh a bash. type -Pw ogóle nie istnieje w Zsh.
kojiro
15

W bash:

type -P vim

W zsh:

type -p vim

Zarówno:

/usr/bin/which vim

Lub:

( unalias vim; type vim )
Mikel
źródło
2
Ostatni jest fajny. Możemy mieć do tego alias. :)
balki
W bash na redhat muszę użyć typu -P, a nie które, jeśli chcę poprawną odpowiedź. Nie dotyczy to aliasów ani funkcji.
Dr Eval, który „który”? Który czerwony kapelusz?
Mikel
@Mikel RH7.4. GNU które v2.20.
4

W Zsh whichjest wbudowane, ponieważ to polecenie informuje:

$ whence -w which
which: builtin

Aby wykonać polecenie zewnętrzne (w dowolnej powłoce) which, użyj pełnej ścieżki :

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

w ten sposób polecenie lszostało znalezione (wartość wyjściowa 0) i znajduje się na /bin/ls.

Wewnątrz zsh; sposobem (oprócz powyższego) wyszukiwania zewnętrznych poleceń jest:

$ whence -p ls
/bin/ls

Jednak to nie rozwiąże zagnieżdżonych aliasów, takich jak:

$ alias dire='ls -l'

Polecenie zgłosi, że nie direznaleziono polecenia.

$ whence -p dire; echo $?
1

Aby rozwiązać problem zagnieżdżonych aliasów (ręcznie), patrz Resolve nested aliases to their source commands

HalosGhost
źródło
2

Mój zdefiniowany jako taki

alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
Meitham
źródło
1

Spróbuj wykonać następujące czynności:

which --skip-alias vim
SiegeX
źródło
1
Ciekawy! Działa to na Bash, ale nie na Zsh (tak naprawdę nie sądziłem, że to będzie zależne od powłoki). To uświadomiło mi, że whichtak naprawdę jest to wbudowana powłoka, a nie zwykłe narzędzie uniksowe, jak zakładałem. Więc powinienem edytować moje pytanie i podać Zsh. Dzięki za zwrócenie mi na to uwagi!
Adrian Petrescu
whichnie jest wbudowany, przynajmniej nie na Debianie. Jest to skrypt powłoki i część debianutils, więc działa na zsh. Jednak --skip-aliasnie jest opcją whichna Debianie. Czy istnieją różne odmiany whichlatania? To nie wydaje się być znormalizowanym poleceniem.
Faheem Mitha
@Faheem Mitha: Jest to wbudowany program zsh. Zobaczyć man zshbuiltins. która nazwa [-wpams] ... Odpowiednik wherece -c.
Mikel
Tak na Xubuntu bash, nie jest to wbudowane i nie ma --skip-aliasopcji.
polim
W CentOS (i RHEL?) 6 jest to plik wykonywalny /usr/bin/whichplus alias, /etc/profile.dktóry pozwala na obsługę aliasów, ale --skip-aliasdziała. W rezultacie which whichpokazuje alias, ale command which whichpokazuje plik wykonywalny!
dave_thompson_085
0

Innym jest alternatywą command which vim, która działa w ten sam sposób w obu zshibash

Np. Na moim komputerze Mac:

LOLcalhost :: ~ % command which grep
/usr/local/bin/grep
Zee Alexander
źródło
Ach, wystarczy.
Zee Alexander
0

Oba typei whichzachowują się inaczej w zależności od typu powłoki.

W bash whichto polecenie istnieje w PATH. Przeszukuje podane polecenie PATH. Wbudowane Bash type -P(P for PATH) zachowuje się dokładnie tak samo which.

W ZSH zarówno whichi typesą wbudowane, jak i częściowe funkcje wbudowane whence. which -pjest tym, czego chcesz. Wymusza wyszukiwanie ścieżki. ( -Popcja nie jest dostępna dla typeZSH.)

whence [-vcwfpamsS] [-x num] name ...

-p

Wyszukaj ścieżkę dla nazwy, nawet jeśli jest to alias, słowo zastrzeżone, funkcja powłoki lub wbudowane.

Więcej z instrukcji ZSH.

które [-wpamsS] [-x num] nazwa ...

Odpowiednik skąd -c.

Aby pominąć builtin whichi wymusić użycie polecenia whichz PATHZSH:

alias which="command which"
Simba
źródło