it-swarm.com.de

Kann ich Funktionen in Bash "exportieren"?

source some_file

some_file:

doit ()
{
  echo doit $1
}
export TEST=true

Wenn ich some_file als Quelle habe, stehen die Funktion "doit" und die Variable TEST in der Befehlszeile zur Verfügung. Aber dieses Skript ausführen:

script.sh:

#/bin/sh
echo $TEST
doit test2

Gibt den Wert von TEST zurück, generiert jedoch einen Fehler bezüglich der unbekannten Funktion "doit".

Kann ich die Funktion auch "exportieren" oder muss ich some_file in script.sh als Quelle verwenden, um die Funktion dort zu verwenden?

96
Nils

In Bash können Sie Funktionsdefinitionen mit in eine Sub-Shell exportieren

export -f function_name

Zum Beispiel können Sie dieses einfache Beispiel ausprobieren:

./script1:

    #!/bin/bash

    myfun() {
        echo "Hello!"
    }

    export -f myfun
    ./script2

./script2:

    #!/bin/bash

    myfun

Wenn Sie dann ./script1 Sie sehen die Ausgabe Hallo!.

142
enzotib

Durch "Exportieren" einer Funktion mit export -f Wird eine Umgebungsvariable mit dem Funktionskörper erstellt. Betrachten Sie dieses Beispiel:

$ fn(){ echo \'\"\ \ \$; }
$ export -f fn
$ sh -c printenv\ fn
() {  echo \'\"\ \ \$
}

Dies bedeutet, dass nur die Shell (nur Bash?) Die Funktion akzeptieren kann. Sie können die Funktion auch selbst einstellen, da der Bash nur Envvars berücksichtigt, die mit () { Beginnen, als Funktion:

$ fn2='() { echo Hi;}' sh -c fn2
Hi
$ fn3='() {' sh -c :
sh: fn3: line 1: syntax error: unexpected end of file
sh: error importing function definition for `fn3'

Wenn Sie diese Variable über SSH "exportieren" müssen, benötigen Sie die Funktion wirklich als Zeichenfolge. Dies kann mit der Druckoption (-p) Für Funktionen (-f) Des integrierten declare erfolgen:

$ declare -pf fn
fn () 
{ 
    echo \'\"\ \ \$
}

Dies ist sehr nützlich, wenn Sie komplexeren Code haben, der über SSH ausgeführt werden muss. Betrachten Sie das folgende fiktive Skript:

#!/bin/bash
remote_main() {
   local dest="$HOME/destination"

   tar xzv -C "$dest"
   chgrp -R www-data "$dest"
   # Ensure that newly written files have the 'www-data' group too
   find "$dest" -type d -exec chmod g+s {} \;
}
tar cz files/ | ssh [email protected] "$(declare -pf remote_main); remote_main"
18
Lekensteyn

Aufbauend auf @ Lekensteyns Antwort ...

Wenn du benutzt declare -pf Es werden alle zuvor definierten Funktionen in der aktuellen Shell an STDOUT ausgegeben.

An diesem Punkt können Sie STDOUT nach Belieben umleiten und die zuvor definierten Funktionen praktisch überall dort einfügen, wo Sie möchten.

Die folgende Antwort fügt sie in eine Variable ein. Dann geben wir diese Variable plus den Aufruf der Funktion wieder, die in die neue Shell ausgeführt werden soll, die als neuer Benutzer erzeugt wird. Wir tun dies, indem wir Sudo mit dem -u (aka. user) schalten und einfach Bash ausführen (der das gepipte STDOUT als auszuführende Eingabe erhält).

Da wir wissen, dass wir von einer Bash-Shell zu einer Bash-Shell wechseln, wissen wir, dass Bash die zuvor definierten Funktionen der Shells korrekt interpretiert. Die Syntax sollte in Ordnung sein, solange wir zwischen einer Bash Shell derselben Version und einer neuen Bash Shell derselben Version wechseln.

YMMV, wenn Sie zwischen verschiedenen Shells oder zwischen Systemen wechseln, die möglicherweise unterschiedliche Versionen von Bash haben.

#!/bin/bash
foo() {
  echo "hello from `whoami`"
}

FUNCTIONS=`declare -pf`; echo "$FUNCTIONS ; foo" | Sudo -u otheruser bash
# $./test.sh
# hello from otheruser
8
Jesse

Sie können keine Funktionen exportieren, nicht so, wie Sie es beschreiben. Die Shell lädt nur das ~/.bashrc Datei am Anfang einer interaktiven Shell (Suche nach "Invocation" in der Bash Manpage ).

Sie können eine "Bibliothek" erstellen, die beim Starten des Programms geladen wird:

source "$HOME/lib/somefile"

Und platzieren Sie dort Ihre nicht interaktiven Funktionen und Einstellungen.

5
Arcege

eval "$(declare -F | sed -e 's/-f /-fx /')" exportiert alle Funktionen.

Ich mache dies oft, bevor ich eine interaktive Shell in einem Skript starte, damit ich im Skriptkontext debuggen und arbeiten kann, während ich seine Funktionen und Variablen verwende.

Beispiel:

eval "$(declare -F | sed -e 's/-f /-fx /')"
export SOME IMPORTANT VARIABLES AND PASSWORDS
bash -i
2
Schlomo

Funktionen werden nicht in Unterprozesse exportiert. Aus diesem Grund gibt es Dateien mit den Namen .kshrc oder .bashrc: Zum Definieren von Funktionen, die auch in Subshells verfügbar sein sollen.

Wenn Sie ein Skript ausführen, werden die. * Shrc-Skripte normalerweise nicht bezogen. Sie müssten das explizit codieren, wie in . ~/.kshrc.

1
ktf
declare -x -f NAME

Mehr Info

 - f Beschränken Sie die Aktion oder Anzeige auf Funktionsnamen und Definitionen 
 - x, damit NAMEs exportiert werden 
1
Steven Penny

Nun, ich bin neu in Linux, aber Sie können dies versuchen. Nennen wir es in einer Datei "tmp/general". Sie erstellen Ihre Funktion:

func1(){
   echo "func from general"
}

Fügen Sie in Ihrem Shell-Skript Folgendes hinzu:

. /tmp/general

und Renn:

func1

Sie werden auf dem Bildschirm angezeigt: func from general.

1
noone