Exportieren einer Funktion in der Shell

87

Bitte sagen Sie mir, wie eine Funktion in die übergeordnete Shell (bash, sh oder ksh) exportiert wird, damit die Funktion für alle vom übergeordneten Prozess gestarteten untergeordneten Prozesse verfügbar ist.

Sachin Chourasiya
quelle
1
unix.stackexchange.com/questions/22796/…
Ciro Santilli 法轮功 冠状 病 六四. 23

Antworten:

104

Die export -fFunktion ist spezifisch für Bash:

Elternteil

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

Kind

#!/bin/bash
echo $(plus1 $(($1 * $2)) )
Bis auf weiteres angehalten.
quelle
2
Ist die exportierte Funktion nur für untergeordnete Anrufe verfügbar? Wie wende ich es auf die aktuelle Bash-Sitzung an? Ich schreibe gerne .bashrc, aber nur für die aktuelle Bash-Instanz ...
vp_arth
3
@vp_arth: Wenn Sie die Funktion in untergeordneten Aufrufen nicht benötigen, müssen Sie sie nicht exportieren. Es ist in beiden Fällen in der aktuellen Sitzung verfügbar (beachten Sie, dass Sie die Datei, wenn sie in einer Datei definiert ist, als Quelle ausführen müssen, anstatt sie auszuführen, um sie in der aktuellen Sitzung verfügbar zu machen).
Bis auf weiteres angehalten.
3

Wenn Sie ksh oder zsh verwenden:

Sie können die Umgebungsvariable verwenden FPATH , in der Sie alle Ihre Funktionen platzieren können.

Wenn FPATH ein interaktiver Interpreter festgelegt ist und in der aktuellen Shell-Umgebung oder in der aktuellen Shell-Umgebung oder kein Befehl oder keine Funktion gefunden wird PATH, werden die dort aufgeführten Verzeichnisse nach einer Datei durchsucht, die nach dem fehlenden Befehl benannt ist. Wenn eines gefunden wird, wird es in der aktuellen Shell-Umgebung bezogen und soll die Funktion definieren.

So können Sie alle Ihre Funktionen an einem Ort in platzieren FPATH , und untergeordnete Skripte können sie auch finden.

Mit dem autoloadBefehl in Shell-Skripten können Sie die gewünschten Funktionen laden:

autoload fun_a fun_b

In zsh autoloadist erforderlich, um FPATHzu arbeiten. kshIch glaube, dass es in und seinen nahen Verwandten einfach Funktionen verursacht, die in definiert sindFPATH regulären Befehl in Ihrem PATH überschreiben, als würden sie direkt definiert.

Einige Details zu FPATHund autoload:

Venkataramesh Kommoju
quelle
2

Wenn Sie Subshells mit erstellen, ( )erben diese einen Snapshot aller Definitionen, Parameter und Shell-Variablen.

Wenn Sie sie wie Programme ausführen, können Sie die Definitionen eingeben .bashrc.

Wenn Sie versuchen, ein vorhandenes Skript zu fälschen, um einen Wrapper auszuführen oder einen PATH-Befehl zu ersetzen, .bashrcfunktioniert dies abhängig von den Details der Ausführung. Wenn nicht, können Sie stattdessen ein Wrapper-Skript ausführen, das einfach eine .oder sourceeine Include-Datei ausführt , die die Funktionen definiert, und dann dasselbe mit dem Shell-Skript mit den zu ersetzenden Befehlen ausführt .

Das Wrapper-Skript könnte ungefähr so ​​aussehen:

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

Die Idee ist, dass der erste Parameter der Name des realen Skripts ist und die verbleibenden Parameter die Argumente sind. Dann wird stattdessen das obige Skript ausgeführt.

DigitalRoss
quelle
2
Könnten Sie diese bitte anhand eines Codierungsbeispiels erläutern? Ich möchte meine Funktion nicht in .bashrc
Sachin Chourasiya
1
declare -x -f NAME

Mehr Info

-f Aktion oder Anzeige auf Funktionsnamen und Definitionen beschränken
-x, um NAMEs exportieren zu lassen
Steven Penny
quelle
6
Bitte beachten Sie, dass dies spezifisch für istbash . ( ksh‚S Gegenstück zu declare, typesethat eine -xOption, aber es gilt nur für Variablen , nicht Funktionen, dito für zsh).
mklement0
0

Funktionen können von Natur aus nicht exportiert werden. Sie können jedoch Zeichenfolgen exportieren, daher habe ich hier einen kleinen Trick:

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

Um die Funktion zu importieren, definieren Sie sie aus der exportierten Zeichenfolge neu:

# in subshell
eval "$func"
iBug
quelle