2013-05-27 4 views
10

È possibile sovrascrivere una funzione di shell e mantenere un riferimento a quello originale?Sovrascrivere una funzione di shell, mantenere un riferimento a quello originale

f() { echo original; } 
f() { echo wrapper; ...; } 
f 

L'output di questo dovrebbe essere:

wrapper 
original 

Questo è possibile in modo semi-portatile?

Razionale: sto provando a testare il mio programma sostituendo parti di esso con funzioni di shell che registrano le loro chiamate in un file di registro. Funziona bene finché ho solo comandi e comandi incorporati, e finché non mi interessa il logging indiscriminato. Ora mi piacerebbe rendere la suite di test più manutenibile registrando solo il pezzo interessante in ciascun test.

Quindi diciamo che il mio programma è costituito da

f 
g 
h 

dove f, g, h sono tutte le funzioni di shell, e mi piacerebbe rintracciare l'esecuzione di appena g.

+0

ciò che si vuole si può fare, ma non molto portabile. –

risposta

3

Molte shell (zsh, ksh, bash almeno) supportano typeset -f f per scaricare il contenuto di f(). Da utilizzare per salvare la definizione corrente in un file; quindi, definire f() come desiderato. Ripristina f() procurando il file creato con typeset.

Se si modifica leggermente la funzione di oggetto di dumping (rinominando f()-_f() sulla prima riga, un po 'più complicato quando f() è ricorsiva o chiama altre funzioni si frobbed allo stesso modo), si può probabilmente ottenere questo per produrre il uscita desiderata

+0

Un altro comando simile: 'declare -f f' Non è sicuro quale sia più portatile ... – anishsane

+0

Né' typeset' né 'declare' sono POSIX (numero 8, 2013). – Jens

+0

@Jens: intendi il numero 7 TC1 (edizione 2013). Il problema 8 non è ancora stato rilasciato. :) –

4

La risposta di Jens è corretta. Basta aggiungere il codice seguente per completezza.

Si può semplicemente utilizzare come qui sotto:

eval "`declare -f f | sed '1s/.*/_&/'`" #backup old f to _f 

f(){ 
    echo wrapper 
    _f # pass "[email protected]" to it if required. 
} 

avevo usato stessa logica qui: https://stackoverflow.com/a/15758880/793796

+0

+1 per l'idea con eval. – Jens

+1

+1. Ho anche usato questa tecnica [qui] (http://askubuntu.com/questions/73262/how-do-i-teach-bash-in-ubuntu-some-curse-words/73282#73282) –

+0

@glennjackman: I è piaciuta l'idea di alias_function :) – anishsane

Problemi correlati