Esecuzione di un eseguibile in PATH con lo stesso nome di una funzione esistente


16

A volte definisco una funzione che ombreggia un eseguibile e ne modifica gli argomenti o l'output. Quindi la funzione ha lo stesso nome dell'eseguibile e ho bisogno di un modo per eseguire l'eseguibile dalla funzione senza chiamare ricorsivamente la funzione. Ad esempio, per eseguire automaticamente l'output di fossil diffthrough colordiffe less -Rutilizzo:

function fossil () {
    local EX=$(which fossil)
    if [ -z "$EX" ] ; then
        echo "Unable to find 'fossil' executable." >&2
        return 1
    fi
    if [ -t 1 ] && [ "$1" == "diff" ] ; then
        "$EX" "$@" | colordiff | less -R
        return
    fi
    "$EX" "$@"
}

Se fossi sicuro della posizione dell'eseguibile, potrei semplicemente digitare /usr/bin/fossil. Bash riconosce che /significa che il comando è un eseguibile, non una funzione. Ma poiché non conosco la posizione esatta, devo ricorrere alla chiamata whiche al controllo del risultato. c'è un modo più facile?


1
Dici "Bash riconosce che /il comando è un eseguibile, non una funzione". A rigor di termini, non è vero. In quella che credo sia una decisione di design orribile (e non documentata), bash consente ai nomi delle funzioni di contenere barre. Le barre causano semplicemente /usr/bin/fossiluna stringa diversa da fossil, quindi, quando dici /usr/bin/fossil, non tenta di eseguire la fossilfunzione.
G-Man dice "Ripristina Monica" l'

Risposte:


19

Usa la commandshell integrata:

bash-4.2$ function date() { echo 'at the end of days...'; }

bash-4.2$ date
at the end of days...

bash-4.2$ command date
Mon Jan 21 16:24:33 EET 2013

bash-4.2$ help command
command: command [-pVv] command [arg ...]
    Execute a simple command or display information about commands.

    Runs COMMAND with ARGS suppressing  shell function lookup, or display
    information about the specified COMMANDs.  Can be used to invoke commands
    on disk when a function with the same name exists.

2
Un'altra opzione è quella di sfuggire al comando \date.
Giordania,

4
@jordanm, che funziona solo per gli alias. La domanda riguardava le funzioni. pastebin.com/TgkHQwbb
arte

3

Negli script, la #!linea spesso usa /bin/env bashper eseguire il comando bash in base al percorso. (Potrebbe differire per alcune utility). Questo dovrebbe funzionare anche qui ...

(L' commandalternativa dovrebbe anche funzionare, ma potrebbe dipendere da una shell specifica) (Funziona su Bourne Shell su Solaris, ma in realtà funziona /bin/commandin quel caso, che è una shell integrata su Bash)

Entrambi /bin/commanded /bin/envè elencato in SUS, quindi tutte le implementazioni conformi dovrebbero averlo.


Grazie per averlo segnalato env. Avevo dei dubbi sulla risposta che avrei dovuto accettare, ma poiché la domanda riguarda bash , il suo built-in commandè la soluzione migliore.
Petr Pudlák,

1
Sul mio Linux non c'è commandeseguibile, ma commandfunziona anche in dash, kshe zsh. Quindi suppongo che sia una shell integrata non solo bash. pastebin.com/fi3gyNse
manatwork

Non è un buildin su Solaris 10 Bourne (disponibile anche come cimelio-sh). Il vantaggio di un eseguibile con un percorso noto è che non può essere sovrascritto da una funzione.
Gert van den Berg,

(L'assenza del comando / bin / potrebbe spiegare perché gli script usano /bin/envdopo l'hash-bang se non vogliono codificare il percorso della shell)
Gert van den Berg

3

La risposta di Gert mi ha fatto capire che si può usare anche niceper lo scopo (in realtà l'ho avuto in uno dei miei script senza accorgermene):

$ function date() { echo 'at the end of days...'; }
$ date
at the end of days...
$ nice -n0 date
Mon Jan 21 16:45:21 CET 2013

È meno elegante delle altre risposte, ma in alcune circostanze potrebbe essere un'opzione utile.


Si consiglia di espandere questa per includere una simile alternativa: `which date`.
Eliah Kagan,

1
@EliahKagan Il problema `which something`è che se non ci sono somethingfile eseguibili, possono succedere cose spiacevoli. Ad esempio, se echomanca, `which echo` /bin/rm preciousFilefa qualcosa di molto diverso dal previsto.
Petr Pudlák 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.