it-swarm.com.de

So verwenden Sie den Export mit Python unter Linux

Ich muss einen Export wie folgt in Python machen:

# export MY_DATA="my_export"

Ich habe versucht zu tun:

# -*- python-mode -*-
# -*- coding: utf-8 -*-
import os
os.system('export MY_DATA="my_export"')

Beim Exportieren der Liste wird "MY_DATA" jedoch nicht angezeigt:

# export

Wie kann ich mit Python exportieren, ohne "my_export" in eine Datei zu speichern?

45
Kevin Campion

Du willst es eigentlich tun

import os
os.environ["MY_DATA"] = "my_export"
59
Alex

export ist ein Befehl, den Sie direkt an die Shell geben (z. B. bash), um sie anzuweisen, eine ihrer Umgebungsvariablen hinzuzufügen oder zu ändern. Sie können die Umgebung Ihrer Shell nicht von einem untergeordneten Prozess (wie Python) aus ändern. Dies ist einfach nicht möglich.

Hier ist was mit Ihnen passiert, versuchen Sie os.system('export MY_DATA="my_export"')...

/bin/bash process, command `python yourscript.py` forks python subprocess
 |_
   /usr/bin/python process, command `os.system()` forks /bin/sh subprocess
    |_
      /bin/sh process, command `export ...` changes local environment

Wenn der unterste /bin/sh-Unterprozess die Ausführung Ihres export ...-Befehls beendet, wird er zusammen mit der gerade von Ihnen geänderten Umgebung verworfen.

71
alex tingle

Eine andere Möglichkeit, dies zu tun, wenn Sie es eilig haben und den hackigen Nachgeschmack nicht stören, besteht darin, die Ausgabe des Python-Skripts in Ihrer bash-Umgebung auszuführen und die Befehle zum Einstellen der Umgebung in Python auszudrucken. Nicht ideal, aber es kann die Arbeit zur Not erledigen. Es ist nicht sehr portabel für Shells, so YMMV.

$(python -c 'print "export MY_DATA=my_export"')

(Sie können die Aussage auch in Backticks in einige Shells einschließen. ``)

12
mikepk

Nicht so einfach:

python -c "import os; os.putenv('MY_DATA','1233')"
$ echo $MY_DATA # <- empty

Aber:

python -c "import os; os.putenv('MY_DATA','123'); os.system('bash')"
$ echo $MY_DATA #<- 123
8
phoku

Sie können stattdessen os.environ ["MY_DATA"] versuchen.

1

Irgendwie ein Hack, weil hier nicht wirklich Python etwas Besonderes tut, aber wenn Sie den Exportbefehl in derselben Sub-Shell ausführen, werden Sie wahrscheinlich das gewünschte Ergebnis erhalten.

import os

cmd = "export MY_DATA='1234'; echo $MY_DATA" # or whatever command
os.system(cmd)
0

In der Hoffnung, Klarheit über gemeinsame Infektionen zu schaffen ...

Ich habe viele Python <-> Bash <-> Elfbin Toolchains geschrieben und der richtige Weg, um es zu sehen, ist wie folgt:

Jeder Prozess (Originator) hat einen Zustand der Umgebung, der von dem übernommen wurde, was er aufgerufen hat. Jede Änderung bleibt lokal an diesem Prozess. Das Übertragen eines Umgebungszustands ist eine Funktion für sich und verläuft in zwei Richtungen mit jeweils eigenen Vorbehalten. Am häufigsten müssen Sie die Umgebung ändern, bevor Sie einen Unterprozess ausführen. Schauen Sie sich den exec () - Aufruf in C an. Es gibt eine Variante, die einen Zeiger auf Umgebungsdaten nimmt. Dies ist die einzige tatsächlich unterstützte Übertragung von Umgebungen in typischen Betriebssystemen.

Shell-Skripts erstellen einen Status, der übergeben wird, wenn untergeordnete Elemente ausgeführt werden, wenn Sie export ausführen. Ansonsten benutzt es nur das, was es überhaupt bekommen hat.

In allen anderen Fällen handelt es sich um einen generischen Mechanismus, der verwendet wird, um einen Datensatz zu übergeben, damit der aufrufende Prozess seine Umgebung basierend auf dem Ergebnis der Ausgabe der Child-Prozesse aktualisieren kann.

Ex:

ENVUPDATE = $(CMD_THAT_OUTPUTS_KEYVAL_LISTS)
echo $ENVUPDATE > $TMPFILE
source $TMPFILE

Dasselbe kann natürlich mit json, xml oder anderen Dingen durchgeführt werden, solange Sie die Werkzeuge zur Interpretation und Anwendung haben.

Die Notwendigkeit hierfür kann (50% ige Chance) ein Zeichen dafür sein, dass die grundlegenden Grundelemente falsch ausgelegt werden und dass Sie einen besseren Konfigurations- oder Parameteraustausch in Ihrer Lösung benötigen.

Oh, in Python würde ich so etwas tun wie ... (Verbesserungsbedarf je nach Situation)

import re

RE_KV=re.compile('([a-z][\w]*)\s*=\s*(.*)')

OUTPUT=RunSomething(...) (Assuming 'k1=v1 k2=v2')

for kv in OUTPUT.split(' ')
  try:
    k,v=RE_KV.match(kv).groups()
    os.environ[k]=str(v)
  except:
    #The not a property case...
    pass
0
OriginalNewBee

Einzeilige Lösung:

eval `python -c 'import sysconfig;print("python_include_path={0}".format(sysconfig.get_path("include")))'`
echo $python_include_path  # prints /home/<usr>/anaconda3/include/python3.6m" in my case

Nervenzusammenbruch:

Python-Anruf

python -c 'import sysconfig;print("python_include_path={0}".format(sysconfig.get_path("include")))'

Es wird ein Python-Skript gestartet 

  1. importiert sysconfig
  2. ruft den Python-Include-Pfad ab, der dieser Python-Binärdatei entspricht (verwenden Sie "which python", um zu sehen, welcher verwendet wird)
  3. gibt das Skript "python_include_path = {0}" aus, wobei {0} der Pfad von 2 ist

Eval call

eval `python -c 'import sysconfig;print("python_include_path={0}".format(sysconfig.get_path("include")))'`

In der aktuellen Bash-Instanz wird die Ausgabe des Python-Skripts ausgeführt. In meinem Fall ist es:

python_include_path=/home/<usr>/anaconda3/include/python3.6m

Mit anderen Worten, es wird die Umgebungsvariable "python_include_path" mit diesem Pfad für diese Shell-Instanz festgelegt.

Inspiriert von: http://blog.tintoy.io/2017/06/exporting-environment-variables-from-python-to-bash/

0
Alechan
import os
import shlex
from subprocess import Popen, PIPE


os.environ.update(key=value)

res = Popen(shlex.split("cmd xxx -xxx"), stdin=PIPE, stdout=PIPE, stderr=PIPE,
            env=os.environ, Shell=True).communicate('y\ny\ny\n'.encode('utf8'))
stdout = res[0]
stderr = res[1]

0
firejoker

Ich habe eine ausgezeichnete Antwort.

#! /bin/bash

output=$(git diff Origin/master..Origin/develop | \
python -c '
  # DO YOUR HACKING
  variable1_to_be_exported="Yo Yo"
  variable2_to_be_exported="Honey Singh"
  … so on
  magic=""
  magic+="export onShell-var1=\""+str(variable1_to_be_exported)+"\"\n"
  magic+="export onShell-var2=\""+str(variable2_to_be_exported)+"\""  
  print magic
'
)

eval "$output"
echo "$onShell-var1" // Output will be Yo Yo
echo "$onShell-var2" // Output will be Honey Singh

Herr Alex Tingle hat Recht mit diesen Prozessen und Unterprozessen

Wie es erreicht werden kann, ist wie oben erwähnt. Schlüsselkonzept ist:

  1. Was auch immer printed aus Python ist, wird in der Variable in der Catching-Variable in bash [output] gespeichert.
  2. Wir können jeden Befehl in Form eines Strings mit eval ausführen
  3. Bereiten Sie also Ihre print-Ausgabe von Python in sinnvollen bash-Befehlen vor
  4. benutze eval um es in bash auszuführen

Und Sie können Ihre Ergebnisse sehen

NOTEFühre die eval immer mit double quotes aus, sonst wird bash deinen \n durcheinander bringen und die Ausgabe wird seltsam

PS: Ich mag bash nicht, aber du musst es benutzen

0
Akhil Soni