Le variabili d'ambiente contenenti funzioni sono un hack bash. Zsh non ha nulla di simile. Puoi fare qualcosa di simile con poche righe di codice. Le variabili di ambiente contengono stringhe; le versioni precedenti di bash, prima che Shellshock fosse scoperto, memorizzavano il codice della funzione in una variabile il cui nome è quello della funzione e il cui valore è () {
seguito dal codice della funzione seguito da }
. È possibile utilizzare il codice seguente per importare variabili con questa codifica e tentare di eseguirle con impostazioni simili a bash. Nota che zsh non può emulare tutte le funzionalità di bash, tutto ciò che puoi fare è avvicinarti un po '(ad es. Per $foo
dividere il valore ed espandere i caratteri jolly e creare array basati su 0).
bash_function_preamble='
emulate -LR ksh
'
for name in ${(k)parameters}; do
[[ "-$parameters[name]-" = *-export-* ]] || continue
[[ ${(P)name} = '() {'*'}' ]] || continue
((! $+builtins[$name])) || continue
functions[$name]=$bash_function_preamble${${${(P)name}#"() {"}%"}"}
done
(Come notato da Stéphane Chazelas , lo scopritore originale di Shellshock, una versione precedente di questa risposta potrebbe eseguire codice arbitrario a questo punto se la definizione della funzione fosse malformata. Questa versione non lo fa, ma ovviamente non appena si esegue un comando, potrebbe essere una funzione importata dall'ambiente.)
Le versioni post-Shellshock di bash codificano le funzioni nell'ambiente usando nomi di variabili non validi (ad es BASH_FUNC_myfunc%%
.). Ciò li rende più difficili da analizzare in modo affidabile poiché zsh non fornisce un'interfaccia per estrarre tali nomi di variabili dall'ambiente.
Non consiglio di farlo. Affidarsi alle funzioni esportate negli script è una cattiva idea: crea una dipendenza invisibile nel tuo script. Se esegui mai lo script in un ambiente che non ha la tua funzione (su un altro computer, in un processo cron, dopo aver modificato i file di inizializzazione della shell, ...), lo script non funzionerà più. Invece, archivia tutte le tue funzioni in uno o più file separati (qualcosa del genere ~/lib/shell/foo.sh
) e avvia i tuoi script importando le funzioni che utilizza ( . ~/lib/shell/foo.sh
). In questo modo, se si modifica foo.sh
, è possibile cercare facilmente quali script si basano su di esso. Se copi uno script, puoi facilmente scoprire quali file ausiliari sono necessari.
Zsh (e ksh prima) lo rende più conveniente fornendo un modo per caricare automaticamente le funzioni negli script in cui vengono utilizzate. Il vincolo è che puoi mettere solo una funzione per file. Dichiarare la funzione come caricata automaticamente e inserire la definizione della funzione in un file il cui nome è il nome della funzione. Metti questo file in una directory elencata in $fpath
(che puoi configurare attraverso la FPATH
variabile d'ambiente). Nel tuo script, dichiara le funzioni caricate automaticamente con autoload -U foo
.
Inoltre zsh può compilare script, per risparmiare tempo di analisi. Chiama zcompile
per compilare uno script. Questo crea un file con l' .zwc
estensione. Se questo file è presente, autoload
verrà caricato il file compilato anziché il codice sorgente. È possibile utilizzare la zrecompile
funzione per (ri) compilare tutte le definizioni delle funzioni in una directory.