Wie kann man ein Bash-Wort zwingen, auf einen Alias, eine Funktion, eine Datei usw. zu verweisen?

13

Beim Versuch, einer verwandten Frage ein bisschen mehr Details hinzuzufügen , wurde mir klar, dass ich nicht genau angeben kann, welcher der verfügbaren Bash-Worttypen ausgeführt werden soll. Entsprechend help typegibt es fünf Wortarten:

  • alias
  • Stichwort
  • Funktion
  • eingebaut
  • Datei

Es ist möglich, dass ein Wort mehrere Typen hat (dies trueist nur ein Beispiel; ein häufig überschriebenes Wort wäre cd):

$ type -a true
true is a shell builtin
true is /bin/true

Wie erzwingen Sie die Ausführung eines bestimmten Synonym? Bisher in der Rangfolge:

  • alias: Dies ist ein Sonderfall, da er Vorrang vor allen anderen Synonymen hat. Dies zu erzwingen wäre nur dann sinnvoll, wenn der Befehl fehlschlagen sollte, wenn der Alias ​​nicht definiert ist.

    $ 
  • Stichwort:

    $ 
  • Funktion:

    $ 
  • eingebaut:

    $ builtin true
  • Datei:

    $ command true
    $ $(which true)
    $ /bin/true

Teillösungen :

  • Das Zitieren eines Wortes schließt Aliase und Schlüsselwörter aus. Das ist,

    $ 'true'

    führt nur die Funktion, das Builtin oder die Datei aus.

l0b0
quelle

Antworten:

10

Was Sie fragen, macht nicht wirklich viel Sinn.

Schlüsselwort bedeutet, dass es ein Wort ist, das Teil der Syntax der Shell ist. Diese werden durch Tokenisierung erkannt. Das Zitieren reicht aus, damit die Shell nicht mehr erkennt.

Es ist jedoch in den meisten Shells möglich, ein Schlüsselwort zu aliasen. Aliase haben also Vorrang vor Keywords (in der Tat werden sie frühzeitig erweitert, und danach gibt es mehr Tokenisierung, bei der Sie mehr Aliase und Keywords haben können) ...

Aliase (mit Ausnahme der mit definierten zsh-Aliase alias -gwerden nur in der Befehlsposition erweitert), also normalerweise nicht in builtin the-alias.

Funktionen haben Vorrang vor integrierten Funktionen und integrierten Funktionen vor externen Befehlen (und $PATHentscheiden dann , welche verwendet werden sollen).

Sie können das Builtin erzwingen mit:

builtin the-cmd and its args

(obwohl es angemerkt werden sollte, ist es kein Standardbefehl).

Sie können Aliase deaktivieren, indem Sie sie in Anführungszeichen setzen (obwohl die angegebene Version in einigen Shells auch mit Alias ​​versehen sein kann).

So zum Beispiel (hier zsh-Syntax) in:

'while'() echo function while
alias 'while=echo alias while'

Das Schreiben while truewürde tatsächlich ausgegeben alias while true, und es gäbe keine Möglichkeit, das whileSchlüsselwort zu verwenden, da durch das Zitieren sowohl der Alias ​​als auch das Schlüsselwort deaktiviert würden.

Sie würden die whileFunktion zum Beispiel aufrufen mit:

'whi'le whatever

Wenn es einen whileeingebauten Code geben würde (aber der würde natürlich nicht in den Shells enthalten sein, die ein whileSchlüsselwort enthalten), würden Sie ihn schreiben:

builtin while whatever

Und um den whileBefehl aufzurufen , schreiben Sie:

env while whatever

oder in zsh(wenn nicht in shEmulation):

command while whatever 

( commandVerhindert in anderen Shells nur Funktionen, keine eingebauten)

Oder

/full/path/to/while whatever

Natürlich hindert Sie nichts daran, noch albernere Dinge zu tun wie:

alias 'while=while "w"hile; do'
"while"() { while "whi"le; done; }

Was zumindest in zsh gültig ist (aber doof).

Stéphane Chazelas
quelle
Das Zitieren unterdrückt die Alias-Suche und command die Funktionssuche, aber keines davon gibt an, welches der verbleibenden Synonyme verwendet wird. Ich suche nach einer Möglichkeit, anzugeben, dass nur ein bestimmtes Synonym ausgeführt werden soll.
10.
@ l0b0 "Befehl" unterdrückt alle Aliasnamen, Schlüsselwörter und eingebauten.
Stéphane Chazelas
Was Sinn macht, builtinwird zum Beispiel in RVM verwendet , um cdfür einen schönen Effekt zu übersteuern .
10.
Du hast recht; und ich habe gerade überprüft, dass es auch Funktionen unterdrückt. +1.
10.
0

Eine äußerst nützliche Redewendung für mich ist:

FALSE=1; TRUE=0
DEVEL_FLAG=$FALSE
...
in_development() { return $DEVEL_FLAG ; }
cd()
{
 if in_development ; then # -D argument to script toggles development flag
   echo "Would run cd $*"
  else
   builtin cd "$@"
 fi
}

Wenn ich jetzt das Skript mit -D ausführe, wird der Entwicklungsmodus aktiviert, und die CD (oder ein anderer umschlossener Befehl) gibt die Debug-Informationen wieder

Dies ist besonders nützlich bei Skripten, die ssh ausführen. Klar, ich könnte set -x umschalten, aber das ist für mich nützlicher und lesbarer.

Graham Nicholls
quelle
1
Wie beantwortet dies die Frage?
l0b0