2016-11-29 3 views
1

Ich habe viele Beispiele gesehen, wie man ein Python-Skript innerhalb eines Bash-Skripts ausführt und entweder Variablen als Argumente übergibt oder den Child-Shell-Zugriff mithilfe von export ermöglicht obwohl.Importieren von Bash-Variablen aus einem Python-Skript

ich ein Python-Skript leite und verfügen über eine separate Datei, lässt es

myGlobalVariables.bash:

foo_1="var1"  
foo_2="var2" 
foo_3="var3" 

Mein Python-Skript diese Variablen verwenden muss myGlobalVariables.bash nennen.

Für ein sehr einfaches Beispiel:

myPythonScript.py:

print "foo_1: {}".format(foo_1) 

Gibt es eine Weise, die ich sie direkt importieren kann? Außerdem möchte ich das Bash-Skript wenn möglich nicht ändern, da es sich um eine allgemeine Datei handelt, auf die an anderer Stelle oft verwiesen wird.

+0

Sie meinen Sie die Bash-Datei von Python analysieren möchten? wird nicht einfach sein. Enthält Ihr Skript neben der Deklaration der Variablen Befehle? –

+0

Es tut, aber nicht viele. Ich habe versucht, Parsing zu vermeiden, aber ich könnte es definitiv tun, wenn das die einzige Option ist. – Bagelstein

+0

Sind die Variablen, auf die Sie verweisen möchten, alle einfachen Zuordnungen? dh 'var_name = var_val' - so dass es keine Shell-Erweiterung, Befehlsersetzung usw. gibt. – theorifice

Antwort

1

Wenn Ihre .bash Datei wie angegeben formatiert ist, können Sie sie möglicherweise direkt als Python-Modul über das Modul imp importieren.

import imp 
bash_module = imp.load_source("bash_module, "/path/to/myGlobalVariables.bash") 
print bash_module.foo_1 
+0

" imp.load_source (Name, Pfadname [, Datei]) Laden und initialisieren Sie ein Modul, das als Python-Quelldatei implementiert ist, und geben Sie das Modul zurück Objekt.". Keine Erwähnung von Bash ... –

+0

Laut der OP Beschreibung von 'myGlobalVariables.bash' - könnte es als eine Python-Datei interpretiert werden. – theorifice

+0

netter Hack. Könnte einfach funktionieren ... ein 'export' und du bist Geschichte :) –

1

Sie können auch verwenden os.environ:

Bash:

#!/bin/bash 
# works without export as well 
export testtest=one 

Python:

#!/usr/bin/python 
import os 
os.environ['testtest'] # 'one' 
+0

In diesem Fall müssen Sie die Datei '.bash' aus Python ausführen - oder sie ausführen, bevor der Python-Code ausgeführt wird. – theorifice

+0

Ausführung in Python wird nicht funktionieren. und vorher: Das OP scheint zu sagen, dass es einfach ist. Und es ist. –

+0

@theorifice Ich denke, die Frage impliziert, dass Python-Skript aus der Bash-Datei aufgerufen wird, nachdem diese Variablen – Marat

0

Ich bin sehr neu zu Python, so würde ich gern gesehen Vorschläge für mehr idiomatische Möglichkeiten, dies zu tun, aber der folgende Code verwendet bash its elf uns zu sagen, welche Werte gesetzt werden, indem zuerst Bash mit einer leeren Umgebung aufrufen (env -i bash), um uns zu sagen, welche Variablen als Baseline gesetzt sind, dann rufe ich es wieder und sagen bash, um Ihre "Variablen" -Datei und dann sagen Sie uns, welche Variablen jetzt gesetzt sind. Nach dem Entfernen einiger falsch-positiver und einer scheinbar leeren Zeile durchlaufe ich den "zusätzlichen" Ausgang und suche nach Variablen, die nicht in der Basislinie waren. Neu erkannte Variablen werden (vorsichtig) aufgeteilt und in das bash Wörterbuch eingefügt. Ich habe meine frühere Idee, exec zu verwenden, um die Variablen nativ in Python zu setzen, hier verlassen (aber auskommentiert), aber ich habe Probleme mit Zitaten/Entweichen bekommen, also bin ich zu einem Diktat übergegangen.

Wenn der genaue Aufruf (Pfad, etc) zu Ihrer "Variablen" -Datei ist anders als meins, dann müssen Sie alle Instanzen dieses Werts ändern - in der subprocess.check_output() Anruf, in der list.remove() Anrufe.

Hier ist die Probe variable Datei, die ich benutze, nur einige der Dinge zu zeigen, was passieren könnte:

foo_1="var1" 
foo_2="var2" 
foo_3="var3" 
if [[ -z $foo_3 ]]; then 
    foo_4="test" 
else 
    foo_4="testing" 
fi 
foo_5="O'Neil" 
foo_6='I love" quotes' 
foo_7="embedded 
newline" 

... und hier ist der Python-Skript:

#!/usr/bin/env python 

import subprocess 

output = subprocess.check_output(['env', '-i', 'bash', '-c', 'set']) 
baseline = output.split("\n") 

output = subprocess.check_output(['env', '-i', 'bash', '-c', '. myGlobalVariables.bash; set']) 
additional = output.split("\n") 

# these get set when ". myGlobal..." runs and so are false positives 
additional.remove("BASH_EXECUTION_STRING='. myGlobalVariables.bash; set'") 
additional.remove('PIPESTATUS=([0]="0")') 
additional.remove('_=myGlobalVariables.bash') 
# I get an empty item at the end (blank line from subprocess?) 
additional.remove('') 

bash = {} 
for assign in additional: 
     if not assign in baseline: 
       name, value = assign.split("=", 1) 
       bash[name]=value 
       #exec(name + '="' + value + '"') 

print "New values:" 
for key in bash: 
    print "Key: ", key, " = ", bash[key] 

Ein anderer Weg, es zu tun:

Inspiriert von Marat 's Antwort, kam ich mit diesem zweistufigen Hack.Beginnen Sie mit einem Python-Programm, nennen wir es "Stufe 1", die subprocess verwendet, um bash aufzurufen, um die Variablendatei zu erhalten, wie meine obige Antwort, aber es teilt Bash mit, alle Variablen zu exportieren und dann den Rest auszuführen Ihr Python-Programm, das sich in "Stufe 2" befindet.

Stufe 1 Python-Programm:

#!/usr/bin/env python 

import subprocess 

status = subprocess.call(
    ['bash', '-c', 
    '. myGlobalVariables.bash; export $(compgen -v); exec ./stage2.py' 
    ]); 

Stufe 2 Python-Programm:

#!/usr/bin/env python 
# anything you want! for example, 
import os 
for key in os.environ: 
    print key, " = ", os.environ[key] 
Verwandte Themen