How to use export with Python on Linux

169,159

Solution 1

export is a command that you give directly to the shell (e.g. bash), to tell it to add or modify one of its environment variables. You can't change your shell's environment from a child process (such as Python), it's just not possible.

Here's what's happening when you try 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 its local environment

When the bottom-most /bin/sh subprocess finishes running your export ... command, then it's discarded, along with the environment that you have just changed.

Solution 2

You actually want to do

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

Solution 3

Another way to do this, if you're in a hurry and don't mind the hacky-aftertaste, is to execute the output of the python script in your bash environment and print out the commands to execute setting the environment in python. Not ideal but it can get the job done in a pinch. It's not very portable across shells, so YMMV.

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

(you can also enclose the statement in backticks in some shells ``)

Solution 4

Not that simple:

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

But:

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

Solution 5

I have an excellent answer.

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

Mr Alex Tingle is correct about those processes and sub-process stuffs

How it can be achieved is like the above I have mentioned. Key Concept is :

  1. Whatever printed from python will be stored in the variable in the catching variable in bash [output]
  2. We can execute any command in the form of string using eval
  3. So, prepare your print output from python in a meaningful bash commands
  4. use eval to execute it in bash

And you can see your results

NOTE Always execute the eval using double quotes or else bash will mess up your \ns and outputs will be strange

PS: I don't like bash but your have to use it

Share:
169,159
Kevin Campion
Author by

Kevin Campion

CTO

Updated on July 05, 2022

Comments

  • Kevin Campion
    Kevin Campion almost 2 years

    I need to make an export like this in Python :

    # export MY_DATA="my_export"
    

    I've tried to do :

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

    But when I list export, "MY_DATA" not appear :

    # export
    

    How I can do an export with Python without saving "my_export" into a file ?

  • Kevin Campion
    Kevin Campion over 14 years
    Indeed I do not see it like that !
  • Kevin Campion
    Kevin Campion over 14 years
    I just realize, after a lot of test, that it's you who is right : I can't change my shell's environment from a child process (such as Python), it's just not possible.
  • Bernardo Kyotoku
    Bernardo Kyotoku almost 12 years
    just reminding that if you run the second line many times, the same amount of recursive bash children will be created.
  • Paco
    Paco almost 11 years
    Basically, you just created a new bash instance on top of python which is on top of another bash
  • Shailen
    Shailen over 9 years
    This solution is not correct. In a python script with many commands, the script will exit as the new bash instance is created.
  • Peter Jenkins
    Peter Jenkins over 8 years
    This doesn't actually work (although it's a nicer way to do this): $ python Python 2.7.10 (default, Sep 8 2015, 17:20:17) [GCC 5.1.1 20150618 (Red Hat 5.1.1-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> os.environ["MY_DATA"] = "my_export" >>> $ export | grep -c MY_DATA 0
  • Ian Gallagher
    Ian Gallagher over 8 years
    Can others comment as to why this got downvoted? It seems like a reasonable solution given the desired requirements. It doesn't start a new subshell, and does actually add new environment variables to the current, running shell process.
  • cubuspl42
    cubuspl42 about 8 years
    @KevinCampion Please change the accepted answer in such case.
  • Nico
    Nico almost 8 years
    Don't do that, creating an entire new bash process just for environment variable is really bad practice.
  • xealits
    xealits over 7 years
    hm.. I tried running subprocess.check_output( 'export x=foo && other_people_command_depending_on_x' ) and it didn't work somehow -- any ideas what happens there? Setting os.environ['x'] = 'foo' for Python (and thus all its' child-processes) works.
  • Krishna Oza
    Krishna Oza over 7 years
    I recently have to do something similar , here is the issue and what has worked for me. The problem was to execute a python script which internally executes a ELF binary and I wanted a certain path to be set for this binary. The solution that worked for me was to fetch the current path variable from the python code and then just directly update the PATH variable using os.putenv. Though this will not update the PATH variable of the shell from where the python script was originally invoked.
  • kevr
    kevr over 6 years
    This doesn't answer the question at all, because this doesn't actually export to the current shell.
  • rhoerbe
    rhoerbe over 5 years
    Actually quite cool. Better that writing a script and souring it later on.
  • dkb
    dkb almost 5 years
    Welcome to SO, Thank you for your contribution, please add some explanation along with the code, which will help SO members to understand your answer better.
  • yann zerlaut
    yann zerlaut over 4 years
    It is indeed an excellent answer !! see also the answer by @mikepk, same idea
  • yann zerlaut
    yann zerlaut over 4 years
    Indeed, quite cool. This and the more detailed version of @Akhil should be the best answer.
  • M Y
    M Y over 4 years
    That will take you to another shell inside the terminal, so, if you put that inside script that has several other commands after that command they will stuck till you return/exit from that new shell.
  • Macilias
    Macilias about 4 years
    export MY_DATA=MY_EXPORT is what I was looking for
  • Rahul Reddy
    Rahul Reddy over 3 years
    the accepted answer is misleading, @KevinCampion need to change the accepted answer based on multiple answers answer1 , answer2, answer3
  • Kevin Campion
    Kevin Campion over 3 years
    Done @RahulReddy