Esportare una funzione in shell


Risposte:


105

La export -ffunzionalità è specifica di Bash:

genitore

#!/bin/bash
plus1 () { echo $(($1 + 1)); }
echo $(plus1 8)
export -f plus1
./child 14 21

bambino

#!/bin/bash
echo $(plus1 $(($1 * $2)) )

2
la funzione esportata è disponibile solo per le chiamate figlio? Come applicarlo alla sessione bash corrente? piace scrivere .bashrc, ma solo per l'istanza bash corrente ...
vp_arth

3
@vp_arth: se non è necessaria la funzione nelle chiamate figlio, non è necessario esportarla. È disponibile in entrambi i casi nella sessione corrente (nota che se è definito in un file, dovrai generare il file anziché eseguirlo per renderlo disponibile nella sessione corrente).
In pausa fino a nuovo avviso.


3

Se stai usando ksh o zsh:

Puoi usare la variabile d'ambiente FPATH, in cui puoi inserire tutte le tue funzioni.

Se FPATHè impostato su un interprete interattivo e un comando o una funzione non viene trovato nell'ambiente di shell corrente o in PATH, nelle directory elencate viene ricercata l'esistenza di un file denominato dopo il comando mancante. Se ne viene trovata una, viene fornita nell'ambiente shell corrente e si prevede che definisca la funzione.

Quindi, puoi posizionare tutte le tue funzioni in una posizione in FPATHe anche gli script figli saranno in grado di trovarle.

È possibile utilizzare il autoloadcomando negli script della shell per caricare le funzioni necessarie:

autoload fun_a fun_b

In zsh, autoloadè richiesto per FPATHfunzionare. In kshe nei suoi parenti stretti, credo che faccia semplicemente in modo che le funzioni definite in FPATHsovrascrivano il comando regolare nel tuo PATH, come farebbero se definite direttamente.

Alcuni dettagli su FPATHe autoload:


1

Se crei subshell con ( ), erediteranno un'istantanea di tutte le definizioni, parametri e variabili di shell.

Se li esegui come programmi, puoi inserire le definizioni .bashrc.

Se stai cercando di falsificare uno script esistente per eseguire un wrapper o la sostituzione di un comando PATH, .bashrcfunzionerà a seconda dei dettagli dell'esecuzione. In caso contrario, potresti invece eseguire uno script wrapper che fa semplicemente un .o sourcedi un file di inclusione che definisce le funzioni e poi fa la stessa cosa con lo script di shell con i comandi da sostituire.

Lo script wrapper potrebbe essere simile a:

script=$1
shift
. include.sh
. $script "$@"

L'idea è che il primo parametro è il nome dello script reale e i parametri rimanenti sono gli argomenti, quindi viene eseguito lo script precedente.


2
Potresti spiegarli con qualche esempio di codice. Non voglio mettere la mia funzione in .bashrc
Sachin Chourasiya

1
declare -x -f NAME

Ulteriori informazioni

-f limita l'azione o la visualizzazione ai nomi e alle definizioni delle funzioni
-x per esportare NAME

6
Si noti che questo è specifico perbash . ( ksh'S controparte declare, typeset, ha un -xopzione, ma si applica solo a variabili , non funzioni; idem per zsh).
mklement0

0

Le funzioni non sono esportabili per natura. Tuttavia puoi esportare le stringhe, quindi ho un piccolo trucco qui:

func="$(typeset -f funcname)"
export func

Per importare la funzione, ridefinirla dalla stringa esportata:

# in subshell
eval "$func"
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.