Umgebungsvariablen mit C-Code abrufen

8

Hier habe ich ein C-Programm geschrieben, das hi.sh file mit system call ausführt.

Hier habe ich . ./hi.sh verwendet, also möchte ich dieses Skript in derselben Shell ausführen und versuche dann, die Umgebungsvariable mithilfe der getenv-Funktion zu erhalten, aber hier bekomme ich eine andere Ausgabe als erwartet.

Die Datei hi.sh enthält

%Vor%

Bedeutet, wenn ich diese hi.sh -Datei mit Systemaufruf ausfühle, setzt export TEST den Wert in derselben Shell auf 10. Danach versuche ich, diesen Variablenwert zu erhalten, aber den angegebenen NULL -Wert.

Und wenn ich dieses Skript manuell von Konsole wie . ./hi.sh ausführe, dann funktioniert es gut und ich bekomme 10 Wert von TEST mit getenv("TEST") Funktion.

Code:

%Vor%

Ausgabe:

%Vor%

Wie kann ich die TEST-Variable in die Programm-Shell exportieren? Wenn system() Befehle in einer anderen Shell ausführt, wie kann ich dann mithilfe von C-Programmcode eine Umgebungsvariable abrufen, die von der über einen system() -Aufruf aufgerufenen Shell exportiert wird?

    
user1089679 03.04.2012, 09:07
quelle

4 Antworten

7

Wie üblich, erklärt die man-Seite das, aber Sie müssen es sehr sorgfältig lesen.

%Vor%

Mit anderen Worten, system () startet zuerst / bin / sh und startet dann / bin / sh den Befehl, den Sie ausführen möchten. Was also hier passiert, ist, dass die Variable TEST in die Shell / bin / sh exportiert wird, die implizit gestartet wird, aber nicht an das Programm, das system () aufgerufen hat.

    
Kristof Provost 03.04.2012, 09:12
quelle
9

Der untergeordnete Prozess kann die Umgebung des übergeordneten Prozesses nicht direkt festlegen. Der Ansatz verwendet system() und getenv() ist also zum Scheitern verurteilt.

Wenn Sie versuchen, ausgewählte Variablen zu importieren, die durch das Skript hi.sh festgelegt wurden, haben Sie mehrere Möglichkeiten. Entweder können Sie das Skript hi.sh lesen und herausfinden, auf was es sie setzen würde (ziemlich schwer), oder Sie können das Skript ausführen und den ausgeführten Code über die relevanten Umgebungsvariablen zurückmelden.

Angenommen, hi.sh setzt $ENV1 und $ENV2 . Sie können popen() verwenden, um die Werte zurück in Ihr Programm zu bringen, und setenv() , um die Umgebung Ihres Programms festzulegen. Im Überblick:

%Vor%

Beachten Sie, dass ich den Variablennamen in die Echoinformationen eingefügt habe. Das vereinfacht das Leben. Wenn Ihre Liste von Variablen unhandlich wird, führen Sie möglicherweise ". ./hi.sh; env" aus, um die gesamte Umgebung abzurufen, und lesen Sie dann jede Zeile und ermitteln Sie anhand Ihrer integrierten Liste, ob eine Variableneinstellung verwendet werden soll oder nicht. Oder Sie können einfach Ihre gesamte Umgebung neu einstellen, wenn es Ihnen gefällt. Sie sollten überprüfen, ob die setenv() -Funktion erfolgreich war (sie gibt Null zurück, wenn sie erfolgreich ist). Sie sollten auch überprüfen, ob popen() erfolgreich war ( fp != 0 ). In diesem Zusammenhang können Sie wahrscheinlich strtok() verwenden, um nach dem = zu suchen, das die Datei trennt Variablenname aus dem Wert; Es trampelt ein Nullbyte über = , was Ihnen einen nullterminierten Namen und einen nullterminierten Wert gibt:

%Vor%     
Jonathan Leffler 03.04.2012 18:03
quelle
1

Eine andere mögliche Lösung ist, Ihr Programm exec selbst durch eine andere Shell zu haben. Diese Shell ersetzt das laufende Programm, liest dann die Umgebungsvariablen und ersetzt dann die Shell durch eine neue Kopie des Programms. Sie müssen der neuen Kopie mitteilen, dass sie bereits eine Exec ausgeführt hat, oder es wird nur wiederholt ausgeführt. Sie können nach der Umgebungsvariablen suchen oder ein Befehlszeilen-Flag übergeben.

Ein ungetestetes Beispiel:

%Vor%

Sie müssten a.out durch den tatsächlichen Programmnamen ersetzen. Wahrscheinlich möchten Sie es aus argv [0] extrahieren und auch den Rest des argv-Arrays übergeben. Aber Sie müssen die Argumente neu formatieren, um als Shell-Argumente zu arbeiten, also müssen sie bei Bedarf zitiert werden, usw.

    
Zan Lynx 20.10.2015 15:14
quelle
0

Sie können die Umgebungsvariable entweder in Ihrem eigenen Prozess mit setenv() setzen (was system() dann automatisch an untergeordnete Prozesse weitergibt oder die Variablen explizit mit fork() und execve() übergeben, um das Shell-Skript auszuführen .

    
Simon Richter 03.04.2012 09:49
quelle

Tags und Links