Globale Variable in Subshell setzen

Tiberian

New Member
Hallo zusammen,

ich schreibe gerade ein Script und dazu eine Funktion fürs Errorhandling.

Der Aufbau ist folgendermaßen:

setProfile.sh:

Code:
...
FUNCFILE=$( grep "FUNCFILE" $CONFFILE | cut -d '=' -f2 )
. $FUNCFILE

RET=$( setProfile )
if [[ "$?" -gt "0" ]]
then
	echo "Profil konnte nicht gesetzt werden"
	exit 49
fi

functions.sh:

Code:
setProfile() {
....
if [ "$VAR" == "$PROFILE" ]
	then
		# Error Funktion aufrufen
		error 1 
		return 76
fi
...
error() { 
	local ERRCODE CARDPORT

	ERRCODE=$1

	CARDPORT=$( getCardPort )
	
	SCRIPTERR=$( eval echo $( cat $CONFFILE | grep "error($ERRCODE)" | cut -d"=" -f2 ) )
export SCRIPTERR
}

Das Script das ausgeführt wird ist setProfile.sh Dies lädt die functions.sh und führt dann diverse Funktionen darin aus.

Mein Problem ist. Ich würde gerne den Error String in der Variable SCRIPTERR exportieren so dass dieser überall auslesbar ist. SCRIPTERR ist definitiv belegt, denn wenn ich sie zurückgeben und dann ausgebe funktioniert es. Wenn ich die Variable aber exportiere funktioniert es nicht. Ich kann sie weder von der aktuellen noch von irgendeiner anderen Shell aus auslesen weil sie nicht existiert.

Eine andere Lösung ist mir dazu nicht eingefallen. Aber falls jemand eine bessere Idee hat dies zu realisieren, ich bin offen für alles :)

EDIT:

Gleich noch eine 2. Frage.

Ich führe in diesem Script SNMP SET und GET auf um verschiedene Parameter zu setzen bzw. zu überprüfen. Allerdings habe ich das Problem, dass wenn der Parameter nicht existiert o.ä. wird der Fehler an STDERR übergeben.
Meine Versuche mit "> /dev/null 2>&1" waren aber bisher nicht erfolgreich dies abzublocken.
Hier mal ein Beispiel:

Code:
RET=$( $SNMPGET -O ve $DSLAM Adsl2-MIB::adsl2LCnfgLineTemplate.$INTID0 | cut -d":" -f2 | tr -d ' ' )

Sollten euch die Infos nicht ausreichen um das Problem zu beschreiben liefere ich gerne nach :)

Danke

Grüße
Tiberian
 
Last edited by a moderator:
Du rufst die Funktion in einer sub-shell auf, die dann die Variable für weitere sub-shells exportiert. Der aufrufenden shell kann man so allerdings keine Variablen übergeben. In Deinem Fall ist es allerdings auch gar nicht nötig, die einzelnen Teile in sub-shell aufzurufen; Du kannst sie auch direkt in der aktuellen shell abarbeiten.
 
Ich hoffe ich hab verstanden worauf Du hinauswillst.

Du meinst ich sollte in der Funktion error() den Errorstring zurückgeben und dann in der setProfile() den String mittels
Code:
ERR=$(error 1)
abfangen und ERR dann an das aufrufende Script zurückgeben (in diesem Fall RET) ?

Wenn ja diese Lösung hatte ich schon auch angedacht. Macht den ganzen Code aber nicht wirklich übersichtlicher.
Es wäre schön gewesen wenn ich vom aufrufenden Script aus darauf zugreifen könnte und da direkt auslesen. Aber dies scheint ja weder mit normalen noch mit exportierten Variablen zu gehen.
Hab schon einen Haufen Seiten abgegrast und in meinem Scripting Buch geblättert, aber dafür scheint die Bash nicht gebaut zu sein...
 
Was ich mit subshell meinte, wird vielleicht aus folgendem Beispiel klar:
Code:
#! /bin/bash

func1() {
    export RETVAR="Hallo $1"
    return 123;
}

echo "Versuch 1 (in sub-shell):"
retval=$( func1 "du" )

echo "RETVAR=$RETVAR"
echo "retval=$retval"

echo
echo "Versuch 2 (in current shell):"
func1 "da"
echo "retval=$?"
echo "RETVAR=$RETVAR"
#
 
Sorry kam jetzt erst dazu zu antworten.

Nu hab ichs verstanden was du meintest und habe es auch gleich ausprobiert. Funktioniert genau so wie ich mir das erhofft hatte.
Danke für deine Hilfe.

Noch jemand ne Idee zu meinem EDIT oben ? Also wie ich die Ausgabe von snmpset/get so umleite das nie etwas auf stdout/stderr ankommt ?

Grüße
Tiberian
 
Code:
$ cat /etc/issue
[COLOR="SeaGreen"]

Welcome to SuSE Linux 9.0 (i586) - Kernel \r (\l).[/COLOR]
$ export tst=`cat /etc/issue 2>/dev/null |sed 's/SuSE/MyLinux/1'`; echo $tst
[COLOR="SeaGreen"]Welcome to MyLinux Linux 9.0 (i586) - Kernel \r (\l).[/COLOR]
$ export tst=`cat /etc/blah |sed 's/SuSE/MyLinux/1'`; echo $tst
[COLOR="SeaGreen"]cat: /etc/blah: No such file or directory[/COLOR]

$ export tst=`cat /etc/blah 2>/dev/null |sed 's/SuSE/MyLinux/1'`; echo $tst

$
 
Hallo LinuxAdmin,

ich habe dein Beispiel mal probiert aber das klappt leider nicht.

So sollte es aussehen wenn der Befehl erfolgreich ist:
Code:
$ snmpget -v 2c -c priv -O ve 192.168.30.28 ATM-MIB::atmVplRowStatus.4456960.1
[COLOR="Lime"]INTEGER: 1[/COLOR]
So gefiltert:
Code:
$ snmpget -v 2c -c priv -O ve 192.168.30.28 ATM-MIB::atmVplRowStatus.4456960.1 | cut -d":" -f2 | tr -d ' '
[COLOR="Lime"]1[/COLOR]

Und das kommt wenn ein Fehler auftritt:
Code:
$ snmpget -v 2c -c priv -O ve 192.168.30.28 ATM-MIB::atmVplRowStatus.4456963.1
[COLOR="Lime"]No Such Instance currently exists at this OID[/COLOR]

Gefiltert mit Fehler:
Code:
$ snmpget -v 2c -c priv -O ve 192.168.30.28 ATM-MIB::atmVplRowStatus.4456963.1 | cut -d":" -f2 | tr -d ' '
[COLOR="Lime"]  [/COLOR]

Allerdings schreibt er den Fehler nicht in STDERR sondern in STDOUT. Wenn ich nun STDOUT umleite nach /dev/null gehen mir auch die gewünschten Werte verloren.
Hast Du ne Idee dazu ?

Grüße
Tiberian
 
Habe es nun gelöst und funktioniert.
Ein grep hatte ich mir auch überlegt, ist aber nicht sinnvoll, da es nicht nur INTEGER vars sind.

Hab es nun so gemacht:

Code:
SNMPSET="$( which snmpset) -c $SNMPCOM -v $SNMPVER > /dev/null 2>&1"
SNMPGET="$( which snmpget) -c $SNMPCOM -v $SNMPVER 2> /dev/null"

Somit wird bei GET nur STDERR umgeleitet und bei SET beides. Mal morgen noch ein paar Tests machen.

Danke nochmal

Grüße
Tiberian
 
Code:
...$(which snmpset) ...
ist ziemlich überflüssig ;) Wenn die Shell den Befehl im Suchpfad hat, brauchst Du den kompletten Pfad nicht angeben, wenn der Befehl nicht im Suchpfad ist, funktioniert es so auch nicht...
 
Back
Top