L'ordine degli eseguibili è iniziato in bash


14

Se eseguo il testcomando in bash, testviene avviata l'utilità integrata (valuta l'espressione condizionale):

$ type test
test is a shell builtin
$ type -a test
test is a shell builtin
test is /usr/local/bin/test
test is /usr/bin/test
$ 

Tuttavia, come visto nell'output di cui type -a testsopra, c'è un'altra testdirectory / usr / local / bin e un'altra ancora nella directory / usr / bin. Come vengono ordinati gli eseguibili, ovvero i comandi integrati sono sempre preferiti e quindi il resto dei comandi dipende dall'ordine della directory nella variabile $ PATH? Inoltre, è possibile modificare l'ordine degli eseguibili avviati, ad es. Se si digita test, viene avviato / usr / bin / test anziché bash-builtin test?


È possibile specificare il percorso completo quando si chiama il comando, ad es., /usr/bin/test -f "$file"...
jasonwryan

@jasonwryan Ne sono consapevole, ma sono interessato solo se c'è un modo per cambiare l'ordine degli eseguibili avviato.
Martin,

Risposte:


25

La massima priorità è bash alias, quindi builtin speciali (solo in modalità POSIX), quindi funzioni, quindi builtin, quindi una ricerca $PATH.

Per eseguire un built-in, utilizzare builtin test.
Per eseguire un'applicazione esterna, utilizzare un percorso esplicito: /bin/test.
Per ignorare funzioni e alias, utilizzare command test.
Per bypassare solo l'alias, utilizzare \testo qualsiasi altro tipo di espansione.

È possibile disabilitare / abilitare un built-in con enable test.

(Aggiornato secondo i commenti qui sotto)
(corretta la modifica errata dell'amministratore che bash ha disableincorporato - in effetti, c'è solo enable)


1
@ 1_CR gena2x ha ragione. La mia risposta ha omesso i builtin speciali, che hanno la precedenza sulle funzioni secondo POSIX (anche se alcune shell non sono conformi; bash è conforme solo in modalità POSIX).
Gilles 'SO- smetti di essere malvagio'

1
Modifica suggerita: gli alias sono disabilitati quando si cita il comando (o parte di esso), come in \testo 'test'o tes't'.
John Kugelman,

2
Non è un quadro completo. Sembra che qualsiasi tipo di espansione (nel manuale di bash, tutta la sostituzione, l'espansione tilde e così chiamata espansione ) disabiliti gli alias. Provai.
gena2x,

1
Dalla pagina del manuale man di bash:.. "La prima parola di ogni comando semplice, se non quotata, viene controllata per vedere se ha un alias Se è così, quella parola è sostituita dal testo dell'alias I personaggi /, $, backtick, e =e uno qualsiasi dei metacaratteri della shell o dei caratteri di citazione sopra elencati potrebbe non apparire in un nome alias. "
John Kugelman,

2
+1 per suggerimenti su come aiutarmi a trovare la fonte di queste informazioni: è nella pagina man di bash, sotto la sezione ESECUZIONE DEI COMANDI, secondo e terzo paragrafo.
twan163,

6

I comandi integrati sono sempre preferiti ai comandi esterni. La logica è che il comando integrato è più veloce (e in alcuni casi, come cdo , solo il comando integrato può avere l'effetto desiderato).test -o BASH_OPTION

A volte il comando esterno può avere funzionalità che la shell incorporata non ha. In tal caso, puoi chiamare il comando esterno fornendo un percorso esplicito (ovvero contenente una barra) (questo elude qualsiasi preoccupazione circa l'ordine in $PATH). Se non si desidera codificare il percorso esterno ma si desidera impedire l'uso dell'integrato, è possibile utilizzare "$(type -P test)"(nota maiuscola P) in bash, "$(whence -p test)"in ksh e =testin zsh. Un altro modo per forzare l'uso di un comando esterno è usare commandbuiltin ( command -p test …) o passare attraverso l' envutility ( env test …).

In zsh, puoi disabilitare un builtin con disable test. Questo è permanente (per l'attuale shell o subshell) fino a quando il builtin non viene riattivato con enable test. In bash, puoi fare lo stesso con enable -n testdisabilitare e enable testriattivare.

È possibile utilizzare un alias o una funzione per forzare l'esecuzione di un comando diverso, ad esempio alias test=/usr/bin/testo test () { /usr/bin/test "$@"; }. Se si dispone di un tale alias, è possibile impedirne l'utilizzo citando qualsiasi parte di esso, ad esempio \testeseguirà la normale funzione / builtin / ricerca esterna. Si noti che a seconda della shell e delle sue impostazioni, le definizioni di alias in una funzione possono essere espanse quando una funzione viene letta o quando viene eseguita. Se hai definito una funzione, puoi usare command testper impedire la ricerca di funzioni e la ricerca di alias (quindi qui testverrà invocato il builtin a meno che non sia disabilitato).


non envsarebbe appropriato anche qui?
Steven Penny,

quindi, se la shell viene eseguita da BusyBox, altri comandi, in genere esterni dallo stesso BusyBox, vengono considerati come interni? ad esempio, ho aggiunto pieno dfa un PERCORSO in prima posizione, rimosso alias 'df', which dfmostra / opt / bin / df, ma df esegue / bin / df -> busybox
papo

@papo which dfnon ti mostra necessariamente cosa dffunziona. unix.stackexchange.com/questions/85249/…
Gilles 'SO- smetti di essere malvagio' il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.