web-dev-qa-db-fra.com

Comment utiliser l'exportation avec Python sur Linux

J'ai besoin de faire une exportation comme celle-ci en Python:

# export MY_DATA="my_export"

J'ai essayé de faire:

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

Mais quand je liste exportation, "MY_DATA" n'apparaît pas:

# export

Comment puis-je exporter avec Python sans enregistrer "my_export" dans un fichier?

45
Kevin Campion

Tu veux vraiment faire

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

export est une commande que vous donnez directement au shell (par exemple, bash), pour lui dire d’ajouter ou de modifier une de ses variables d’environnement. Vous ne pouvez pas modifier l'environnement de votre shell à partir d'un processus enfant (tel que Python), ce n'est tout simplement pas possible.

Voici ce qui se passe avec vous essayez 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

Lorsque le sous-processus /bin/sh situé au bas de la liste termine l'exécution de votre commande export ..., il est ignoré, ainsi que l'environnement que vous venez de modifier.

71
alex tingle

Une autre façon de faire cela, si vous êtes pressé et que cela vous est égal, est d'exécuter la sortie du script python dans votre environnement bash et d'imprimer les commandes à exécuter pour définir l'environnement en python. Pas idéal, mais cela peut faire le travail à la rigueur. Ce n'est pas très portable entre les obus, donc YMMV.

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

(vous pouvez également inclure la déclaration entre guillemets dans certains shells ``)

12
mikepk

Pas si simple:

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

Mais:

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

Vous pouvez essayer os.environ ["MY_DATA"] à la place.

1
Thomas Zoechling

C'est un peu un piratage, car ce n'est pas vraiment un travail python spécial, mais si vous exécutez la commande d'exportation dans le même sous-shell, vous obtiendrez probablement le résultat souhaité.

import os

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

Dans l'espoir de clarifier la cinfusion commune ...

J'ai écrit de nombreuses chaînes d'outils python <-> bash <-> elfbin et la bonne façon de voir cela est la suivante:

Chaque processus (expéditeur) a un état de l'environnement hérité de celui qui l'a invoqué. Tout changement reste lié à ce processus. Le transfert d'un état d'environnement est une fonction en soi et s'exécute dans deux directions, chacune avec ses propres mises en garde. La chose la plus commune est de modifier l'environnement avant d'exécuter un sous-processus. Pour descendre au métal, regardez l'appel exec () - en C. Il existe une variante qui prend un pointeur sur les données d'environnement. C’est le seul transfert d’environnement réellement pris en charge dans un système d’exploitation typique.

Les scripts shell créeront un état à transmettre lors de l'exécution d'enfants lorsque vous effectuez un export . Sinon, il utilise simplement ce qu’il a reçu en premier lieu.

Dans tous les autres cas, il s'agira d'un mécanisme générique utilisé pour transmettre un ensemble de données afin de permettre au processus appelant lui-même de mettre à jour son environnement en fonction du résultat de la sortie des processus enfants.

Ex:

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

La même chose peut bien sûr être faite en utilisant json, xml ou autre chose pourvu que vous ayez les outils pour interpréter et appliquer.

La nécessité de cela peut être (50% de chance) le signe d’une mauvaise interprétation des primitives de base et du fait que vous avez besoin d’une meilleure configuration ou d’un meilleur échange de paramètres dans votre solution .....

Oh, en python, je ferais quelque chose comme ... (Besoin d'amélioration en fonction de votre 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

Une solution en ligne:

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

Panne:

Appel python

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

Il lance un script python qui 

  1. importe sysconfig
  2. récupère le chemin d'inclusion python correspondant à ce binaire python (utilisez "quel python" pour voir lequel est utilisé)
  3. affiche le script "python_include_path = {0}", avec {0} étant le chemin de 2

Appel d'évaluation

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

Il exécute dans l'instance bash actuelle la sortie du script python. Dans mon cas, son exécution:

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

En d'autres termes, il définit la variable d'environnement "python_include_path" avec ce chemin pour cette instance de shell.

Inspiré par: http://blog.tintoy.io/2017/06/exporting-environment-variables-from-python-to-bash/

0
Alechan

J'ai une excellente réponse.

#! /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

M. Alex Tingle a raison sur ces processus et ces sous-processus

Comment cela peut être réalisé est comme ce que j'ai mentionné ci-dessus. Le concept clé est:

  1. Tout ce que printed à partir de python sera stocké dans la variable de la variable de capture dans bash [output]
  2. Nous pouvons exécuter n'importe quelle commande sous forme de chaîne en utilisant eval
  3. Alors, préparez votre sortie print de python dans une commande bash explicite
  4. utilisez eval pour l'exécuter en bash

Et vous pouvez voir vos résultats

NOTEToujours exécuter la eval en utilisant double quotes ou sinon bash gâchera votre \ns et les sorties seront étranges

PS: Je n'aime pas bash mais tu dois l'utiliser

0
Akhil Soni