Wie benutzt man `which` in einem Alias-Befehl?

76

Wie die meisten Benutzer habe ich eine Reihe von Aliasen eingerichtet, um einen Standardsatz von Flags für häufig verwendete Programme bereitzustellen. Zum Beispiel,

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

Das Problem ist, dass, wenn ich verwenden möchte, um whichzu sehen, woher mein vim/ grep/ ls/ etc kommt, der Alias ​​im Weg steht:

$ which vim
vim: aliased to vim -X

Dies ist eine nützliche Ausgabe, aber in diesem Fall nicht das, wonach ich suche. Ich weiß, es vimist ein Alias, vim -Xaber ich möchte wissen, woher das vim kommt.

Gibt whiches eine einfache Möglichkeit which, den Alias zu "entpacken" und sich selbst darauf auszuführen, ohne den Alias ​​vorübergehend zu deaktivieren, damit ich ihn verwenden kann ?

Bearbeiten: Es scheint, dass whiches sich um eine Shell handelt, die über verschiedene Shells hinweg unterschiedliche Verhaltensweisen aufweist. In Bash funktioniert der Vorschlag von SiegeX für die --skip-aliasFlagge. Ich bin jedoch auf Zsh. Gibt es dort etwas Ähnliches?

Adrian Petrescu
quelle
in zsh, wenn Sie wissen wollen, woher das vimkommt , würden Sie verwendenwhere vim
Matija Nalis

Antworten:

105

whichDies ist in der Tat eine schlechte Methode, da hiermit eine Vermutung über Ihre Umgebung $SHELLund die von der Shell verwendeten Startdateien angestellt wird. Es wird nicht nur manchmal falsch geraten, man kann es auch nicht generell dazu bringen, sich anders zu verhalten. ( whichAuf meinem Ubuntu 10.10 wird dies --skip-aliaszum Beispiel von @SiegeX nicht verstanden .) typeVerwendet die aktuelle Shell-Umgebung, anstatt auf Ihre Konfigurationsdateien zuzugreifen, und kann angewiesen werden, Teile dieser Umgebung zu ignorieren, sodass angezeigt wird, was tatsächlich geschieht passieren, anstatt was bei einer Rekonstruktion Ihrer Standard-Shell passieren würde.

In diesem Fall type -Pwerden alle Aliase oder Funktionen umgangen:

$ type -P vim
/usr/bin/vim

Sie können ihn auch bitten, alle Schichten nacheinander abzuziehen und Ihnen zu zeigen, was sie finden würden:

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

(Erweitere dies aus den Kommentaren :)

Das Problem dabei whichist, dass es sich in der Regel um ein externes Programm anstelle einer integrierten Shell handelt. Dies bedeutet, dass Ihre Aliase oder Funktionen nicht angezeigt werden und dass versucht werden muss, sie aus den Startup- / Konfigurationsdateien der Shell zu rekonstruieren. (Wenn es sich um eine eingebaute Shell handelt, wie sie sich zshanscheinend bashin der Shell befindet, ist es wahrscheinlicher, dass sie die Umgebung der Shell nutzt und das Richtige tut.)

typeist ein POSIX-kompatiblen Befehl, wenn es eine eingebaute in waren verhalten erforderlich ist , wie, so ist es in der Regel (das heißt, es die Umgebung der Schale aus , einschließlich der lokalen Alias - Namen und Funktionen es aufgerufen verwenden müssen) ist ein eingebaut.

Es ist im Allgemeinen nicht in csh/ zu finden tcsh, obwohl es in den meisten modernen Versionen whicheine eingebaute Shell ist und das Richtige tut; Manchmal ist whatstattdessen die integrierte Shell vorhanden, und manchmal gibt es keine gute Möglichkeit, die aktuelle Shell-Umgebung von csh/ aus tcshzu sehen.

Geekosaurier
quelle
6
Vielen Dank! Dies ist etwas sehr Nützliches, um es meiner Trickkiste hinzuzufügen. Mir gefällt besonders, dass type -aanscheinend alle Instanzen auf deiner zurückkommen $PATH, nicht nur die erste. Ich denke , ich werde alias :)whichtype
Adrian Petrescu
2
@geekosaur: Danke. Wenn dies typeTeil des POSIX-Standards ist, ist dies der richtige Weg. Um meine Frage zu beantworten, tippe works auch auf zsh (auf Debian). Warum werden die Distributionen nicht entfernt whatund whichwenn sie nicht standardisiert sind und keine zusätzlichen Funktionen haben?
Faheem Mitha
1
Nein, nicht einmal aus der Ferne.
Geekosaurier
1
@Faheem: bezüglich der Dokumentation würde ich mit info bash 'Bash builtins'Linux beginnen, obwohl Sie es auch aus dem zshReferenzhandbuch erhalten können. Offizieller gesagt , pubs.opengroup.org/onlinepubs/009695399/utilities/type.html (was ich nicht wirklich spezifiziere -Poder -asogar -pwas die ursprüngliche Form war -P, aber erfordert, dass es die aktuelle Shell-Umgebung verwendet).
Geekosaurier
2
type -pverhält sich zwischen zsh und bash unterschiedlich. type -Pexistiert überhaupt nicht in zsh.
Kojiro
15

In bash:

type -P vim

In zsh:

type -p vim

Sowohl:

/usr/bin/which vim

Oder:

( unalias vim; type vim )
Mikel
quelle
2
Letzteres ist cool. Wir können einen Alias ​​haben, um dies zu tun. :)
Balki
In Bash auf RedHat muss ich den Typ -P verwenden und nicht den, wenn ich die richtige Antwort haben möchte. Es sind keine Aliase oder Funktionen betroffen.
Dr. Eval, welches "welches"? Welcher Red Hat?
Mikel
@Mikel RH7.4. GNU welche v2.20.
4

In zsh whichist folgendes eingebaut:

$ whence -w which
which: builtin

Verwenden Sie den vollständigen Pfad, um den externen Befehl (in einer beliebigen Shell) auszuführen :which

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

Somit wurde der Befehl lsgefunden (ein Exit-Wert von 0) und befindet sich bei /bin/ls.

Innen zsh; Eine Möglichkeit (neben der obigen), nach externen Befehlen zu suchen , ist:

$ whence -p ls
/bin/ls

Verschachtelte Aliase wie die folgenden werden jedoch nicht aufgelöst:

$ alias dire='ls -l'

Der Befehl meldet, dass kein direBefehl gefunden wurde.

$ whence -p dire; echo $?
1

Informationen zum Auflösen verschachtelter Aliase (manuell) finden Sie unter Resolve nested aliases to their source commands

HalosGhost
quelle
2

Meine als solche definiert

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

Versuche Folgendes:

which --skip-alias vim
SiegeX
quelle
1
Interessant! Dies funktioniert auf Bash, aber nicht auf Zsh (ich hätte wirklich nicht gedacht, dass dies von der Shell abhängt). Dadurch wurde mir klar, dass whiches sich tatsächlich um eine integrierte Shell und nicht um ein reguläres Unix-Dienstprogramm handelt, wie ich angenommen hatte. Also sollte ich meine Frage bearbeiten und Zsh angeben. Danke, dass du mich darauf hingewiesen hast!
Adrian Petrescu
whichist kein Builtin, zumindest nicht auf Debian. Es ist ein Shell-Skript und Teil von debianutils, funktioniert also auf zsh. Allerdings --skip-aliasist das whichunter Debian keine Option . Gibt es verschiedene Arten von whichherumschweben? Dies scheint kein standardisierter Befehl zu sein.
Faheem Mitha
@Faheem Mitha: Es ist ein zsh builtin. Sehen man zshbuiltins. welchen [-wpams] Namen ... Entspricht woher -c.
Mikel
Ja, bei Xubuntu ist bashes nicht eingebaut und hat keine --skip-aliasOption.
Polym
Auf CentOS (und RHEL?) 6 ist es eine ausführbare Datei /usr/bin/whichund ein Alias /etc/profile.d, mit dem Aliase behandelt werden können, der jedoch --skip-aliasfunktioniert. Als Ergebnis which whichzeigt das Alias, command which whichzeigt aber die ausführbare Datei!
Dave_thompson_085
0

Eine andere Alternative ist command which vim, die in beiden zshund auf die gleiche Weise funktioniertbash

ZB auf meinem Mac:

LOLcalhost :: ~ % command which grep
/usr/local/bin/grep
Zee Alexander
quelle
Ah, fair genug.
Zee Alexander
0

Beide typeund whichverhalten sich je nach Shell-Typ unterschiedlich.

In der Bash whichist ein Befehl in vorhanden PATH. Es durchsucht den Befehl, den Sie eingeben PATH. Bash builtin type -P(P for PATH) verhält sich genauso which.

In ZSH sind beides whichund typeBuiltins und Teilfunktionen von Builtin whence. which -pist was du willst. Es erzwingt eine Pfadsuche. ( -POption ist für typeZSH nicht verfügbar .)

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

-p

Führen Sie eine Pfadsuche nach Namen durch, auch wenn es sich um einen Alias, ein reserviertes Wort, eine Shell-Funktion oder eine integrierte Funktion handelt.

Mehr aus dem ZSH-Handbuch.

Welcher [-wpamsS] [-x num] Name ...

Äquivalent zu wherece -c.

Zum Überspringen builtin whichund verwenden Sie den Befehl zu zwingen , whichvon PATHin ZSH:

alias which="command which"
Simba
quelle