2015-12-21 3 views
13

Was ist der beste Weg, um einen Alias ​​zu definieren, wenn, sagen wir, "ag" ausführbare Datei gefunden wird?Der beste Weg, um "bedingte" Aliase in der Shell zu definieren

if (($+commands[ag])) ; then alias grep='ag'; fi 

oder

[[ -s $(which ag) ]] && alias grep='ag' 

oder

if $(which ag >& /dev/null); then alias grep='ag'; fi 

oder ...?

Am besten, ich meine robuster, leistungsfähiger und/oder portabler (Bash, Zsh).

Was ist Ihr Rat?

Antwort

9

Ich sehe nicht, wie die einfache offensichtliche POSIX-Variante irgendwelche Nachteile im Vergleich zu den (meist nicht tragbaren) Alternativen haben würde, die Sie vorschlagen.

type ag >/dev/null 2>&1 && alias grep=ag 
+0

Schön und sauber. Grundsätzlich meine Frage zu beantworten. – user3341592

+0

Side Frage: besser zu verwenden '' 'Typ ag> &/dev/null''' oder einfach' '' Typ ag>/dev/null''' (wie Sie)? – user3341592

+1

Ersteres ist nicht tragbar. Wenn du stderr umleiten willst, ist das '2>/dev/null' oder'>/dev/null2> & 1' für stdout und stderr. – tripleee

1

Ich benutze diese pathto Funktion für die Portabilität auf alle Erbe Schalen Bourne (I nicht which verwenden, weil es nicht in POSIX ist so seine Ausgabeformat nicht spezifiziert ist und es beschwert sich, wenn nichts statt zu schweigen gefunden wird):

pathto() { 
     DIRLIST=`echo $PATH|tr : ' '` 
     for e in "[email protected]"; do 
       for d in $DIRLIST; do 
         test -f "$d/$e" -a -x "$d/$e" && echo "$d/$e" 
       done 
     done 
} 

, die den Pfadnamen für jede ausführbare Echos gegeben, wenn gefunden, zusammen mit

test "`pathto less`" != "" && alias more=less 

was die Leistung, sollten Sie nicht kümmern, weil die Anzahl der Sie pathto vernachlässigbar ist nennen. Ihre ersten zwei Beispiele verwenden die nicht tragbaren (()) und [[ ]] Konstrukte und sollten vermieden werden.

Beachten Sie auch, dass ich nicht speziell mit leeren Teilen in PATH umgehen. Aus Sicherheitsgründen sollten sie wie . vermieden werden.

+2

Dies ist unzuverlässig, wenn Einträge in $ PATH Leerzeichen enthalten. Aber das in Array-losen (und '<(...)' -losen) Bourne-Shells zu reparieren, würde etwas Arbeit erfordern (obwohl "echo" als Ausgabe beibehalten bedeutet, dass Sie dies mit einer normalen Pipe verwenden könnten und "printf" annehmen können Ausgabe '' \ 0'' Sie könnten es tun ... ich denke). Auch das * behandelt * in gewisser Weise leere $ PATH-Werte, da es sie vollständig ignoriert, wenn sie in der Schleife "for d in $ DIRLIST" fallen gelassen werden. Das heißt, dass es die Tatsache vermisst, dass die Shell selbst einen Befehl im aktuellen Verzeichnis sehen wird. –

+1

Dies verwendet auch das veraltete Argument '-a' für' test' und kann nicht mit mehr als einem Befehl verwendet werden, wenn der Befehlsname selbst ein Leerzeichen enthält (ignoriert das Problem '$ PATH' mit Leerzeichen). (Und ja, ich bezweifle ernsthaft, dass dies ein Problem ist, das jemals auftauchen wird, aber ich dachte, es wäre sowieso erwähnenswert.) –

+0

@EtanReisner Deine Pedanterie ist willkommen, danke! :-) Fröhliche Weihnachten. – Jens