Ich habe ein Bash-Skript, das einen Bericht über den Fortschritt einiger lang laufender Jobs auf dem Computer generiert. Grundsätzlich durchläuft dieses übergeordnete Skript eine Liste von untergeordneten Skripten (wobei alle aufgerufen werden source
). Von den untergeordneten Skripten wird erwartet, dass sie einige spezifische Variablen festlegen, die das übergeordnete Skript dann verwendet.
Heute habe ich einen Fehler entdeckt, bei dem eine vom ersten untergeordneten Skript festgelegte Variable versehentlich vom zweiten untergeordneten Skript verwendet wurde und eine falsche Ausgabe verursachte. Gibt es eine saubere Möglichkeit, um das Auftreten solcher Fehler zu verhindern?
Wenn ich source
ein untergeordnetes Skript habe, gibt es grundsätzlich einige spezifische Variablen, die ich für das übergeordnete Skript beibehalten möchte. Mein übergeordnetes Skript setzt diese spezifischen Variablen vor source
jedem neuen untergeordneten Skript zurück, sodass keine Probleme mit ihnen auftreten. Einige untergeordnete Skripte können jedoch zusätzliche beliebige Variablen enthalten, die lokal verwendet werden und die nicht im übergeordneten Skript verbleiben sollten.
Natürlich könnte ich jedes dieser Elemente am Ende des untergeordneten Skripts manuell deaktivieren, aber diese scheinen fehleranfällig zu sein, wenn ich eines vergesse. Gibt es eine geeignetere Möglichkeit, ein Skript zu beschaffen und nur bestimmte Variablen für das aufgerufene Skript beizubehalten source
?
edit: Aus Gründen der Klarheit ist hier eine Art heruntergekommene Version meines übergeordneten Skripts:
echo "<html><body><h1>My jobs</h1>"
FILES=~/confs/*.sh
for f in $FILES; do
# reset variables
name="Unnamed job"
secsSinceActive="Unknown"
statusText="Unknown"
# run the script that checks on the job
source "$f"
# print bit of report
echo "<h3>$name</h3>"
echo "<p>Last active: $secsSinceActive seconds ago</p>"
echo "<p>Status: $statusText</p>"
echo "</body></html>"
Und so könnte eines der untergeordneten Skripte aussehen:
name="My awesome job"
nowTime=`expr $(date +%s) `
lastActiveTime=`expr $(date +%s -r ~/blah.log)`
secsSinceActive=`expr $nowTime - $lastActiveTime`
currentRaw=$(cat ~/blah.log | grep "Progress" | tail -n 1)
if [ -z "$currentRaw" ]; then
statusText="Not running"
else
statusText="In progress"
fi
Die Variablen $ name, $ secsSinceActive und $ statusText müssen im übergeordneten Skript verbleiben, aber alle anderen Variablen sollten verschwinden, wenn das untergeordnete Skript beendet wird.
quelle
source
Teile einer Unterschale aufrufen und überprüfen, damit sie die Eltern nicht dauerhaft beeinträchtigen?Antworten:
Wickeln Sie das gesamte Skript, das Sie als Quelle verwenden möchten, in eine Funktion ein, fügen Sie vor den Deklarationen, die Sie nur in der Funktion verwenden möchten, local hinzu und rufen Sie die Funktion am Ende des Skripts auf.
quelle
func()
Funktion jedoch im übergeordneten Bereich vorhanden bleibt und sie verschmutzt; Um widersprüchliche Namen zu vermeiden, ist die beste Lösung, die ich kenne, ihm einen hässlichen Namen zu geben, so etwas wie___this_main___()
unset -f func
direkt nach dem Aufruf verwenden.Ich glaube, die Syntax zum Erstellen einer lokalen Variablen in bash lautet:
Ich weiß, dass dies für Funktionen funktioniert und bin mir nicht sicher, wie es mit mehreren Skripten funktioniert.
quelle
local: can only be used in a function