source some_file
some_file:
doit ()
{
echo doit $1
}
export TEST=true
Wenn ich some_file schreibe, sind die Funktion "doit" und die Variable TEST in der Kommandozeile verfügbar. 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 angeben, um die Funktion dort zu verwenden?
#!/bin/sh
zu#!/bin/bash
und nachdoit() {...}
nurexport -f doit
#!/bin/sh
empfiehlt sich jedoch, sie zu verwenden#!/bin/bash
, um Probleme zu vermeiden, wenn die Standard-Shell nicht bash ist.Antworten:
In Bash können Sie Funktionsdefinitionen mit in die Sub-Shell exportieren
Zum Beispiel können Sie dieses einfache Beispiel ausprobieren:
./script1
:./script2
:Wenn Sie dann anrufen
./script1
, sehen Sie die Ausgabe Hallo! .quelle
Durch "Exportieren" einer Funktion mit
export -f
wird eine Umgebungsvariable mit dem Funktionskörper erstellt. Betrachten Sie dieses Beispiel: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
() {
als Funktion beginnen:Wenn Sie diese Variable über SSH "exportieren" müssen, benötigen Sie die Funktion wirklich als Zeichenfolge. Dies kann mit der print-Option (
-p
) für Funktionen (-f
) desdeclare
eingebauten getan werden :Dies ist sehr nützlich, wenn Sie komplexeren Code haben, der über SSH ausgeführt werden muss. Betrachten Sie das folgende fiktive Skript:
quelle
fn2='() { echo Hi;}' sh -c fn2
hat bei mir nicht funktioniert. Auf Arch Linux mitsh
Bash v5.0.7 habe ich bekommensh: fn2: command not found
. Auf Ubuntu mit mitsh
Dash v0.2.3 habe ich bekommensh: 1: fn2: not found
. Welchesh
Shell hast du benutzt?f(){ echo a;}; export -f f; echo "$f"; sh -c 'printenv f; echo "$f"'
druckt nichts für mich, wird also eindeutigf
nicht als reine Zeichenkette exportiert. Ich habe mit beiden oben genannten Kombinationen getestet.sh
diese Zeichenfolge als Funktion ausgeführt werden? In Ihrem Beispiel istfn2='() { echo Hi;}' sh -c fn2
der Befehl, der anfn2
gegebensh
wird, buchstäblich die Zeichenfolge"fn2"
.sh
nach einem solchen Befehl in seinem PATH suchen, aber nicht nach einer Variablen suchen$fn2
, diese erweitern und ihren Wert als Funktion ausführen - das klingt für mich nach einem großen Sicherheitsproblem. edit: Ich denke das wars! War Ihr gezeigtes Verhalten der Sicherheitsfehler, der als ShellShock / Bashdoor bekannt ist ?fn(){ echo foo; }; export -f fn; env | grep foo
AusgängeBASH_FUNC_fn%%=() { echo foo
Aufbauend auf @ Lekensteyns Antwort ...
Bei Verwendung
declare -pf
werden alle zuvor in der aktuellen Shell definierten Funktionen an STDOUT ausgegeben.An diesem Punkt können Sie STDOUT an einen beliebigen Ort umleiten und die zuvor definierten Funktionen praktisch an einen beliebigen Ort übertragen.
Die folgende Antwort fügt sie in eine Variable ein. Dann geben wir diese Variable plus den Aufruf der Funktion wieder, die wir in die neue Shell ausführen möchten, die als neuer Benutzer erzeugt wird. Wir tun dies, indem wir
sudo
den Schalter-u
(aka.user
) Verwenden und einfach Bash ausführen (was das gepipte STDOUT als die 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 zwischen einer Bash-Shell derselben Version und einer neuen Bash-Shell derselben Version gewechselt wird.
YMMV, wenn Sie zwischen verschiedenen Shells oder zwischen Systemen wechseln, auf denen möglicherweise unterschiedliche Versionen von Bash installiert sind.
quelle
Sie können keine Funktionen exportieren, nicht so, wie Sie es beschreiben. Die Shell lädt die
~/.bashrc
Datei nur beim Start einer interaktiven Shell (Suche nach "Invocation" in der bash-Manpage ).Sie können eine "Bibliothek" erstellen, die beim Starten des Programms geladen wird:
Und platzieren Sie Ihre nicht interaktiven Funktionen und Einstellungen dort.
quelle
BASH_ENV
Umgebungsvariable so einstellen ,some_file
dass sie bereits vorhanden ist, und sie wird aufgerufen. Es wäre leicht genug, das herauszufinden:echo echo foobar > /tmp/foobar; BASH_ENV=/tmp/foobar $SHELL -c :
eval "$(declare -F | sed -e 's/-f /-fx /')"
exportiert alle Funktionen.Ich mache das 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:
quelle
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 bereitgestellt. Sie müssten das explizit codieren, wie in
. ~/.kshrc
.quelle
rm=rm -i
)Nun, ich bin neu in Linux, aber Sie können dies versuchen. Nennen wir es in einer Datei "tmp / general". Sie erstellen Ihre Funktion:
Fügen Sie in Ihrem Shell-Skript Folgendes hinzu:
und Renn:
Sie werden auf dem Bildschirm angezeigt:
func from general
.quelle
Mehr Info
quelle