1

Converting a shell script to python and trying to find the best way to perform the following. I need this as it contains environment variables I need read.

if [ -e "/etc/rc.platform" ];
then
    . "/etc/rc.platform"
fi

I have the 'if' converted but not sure how to handle the . "/etc/rc.platform" as source is a shell command. So far I have the following

if os.path.isfile("/etc/rc.platform"):
    print "exists" <just to verify the if if working>
    <what goes here to replace "source /etc/rc.platform"?>

I've looked at subprocess and execfile without success.

The python script will need to access the environment variables set by rc.platform

Jason Templeman
  • 431
  • 5
  • 21
  • 3
    You will have to parse `/etc/rc.platform`, extract environment variable names and values, and update [os.environ](http://docs.python.org/2/library/os.html#os.environ) accordingly. – crayzeewulf Mar 07 '13 at 16:28
  • @crazyeewulf - It is not just about environment variables, there could also be bash functions that could be exported by the script. How do you plan to use them from the python script, unless you somehow try to reuse the same shell for all the scripts which are invoked. – Tuxdude Mar 07 '13 at 16:35
  • 1
    I suggest porting `/etc/rc.platform` to Python as well, since `.` is very similar to `import`. – chepner Mar 07 '13 at 16:40
  • 1
    If you are trying to re-write the script in python, then you will very likely want to rewrite /etc/rc.platform in python. If it is merely making variable assignment, you can make it a config file. In the general case, what you are trying to do is difficult. – William Pursell Mar 07 '13 at 16:41
  • @Tuxdude you are correct for a general case. But OP mentioned in the question that "I need this as it contains environment variables I need read." So I expected that OP probably does not care about anything other than environment variables from this file. – crayzeewulf Mar 07 '13 at 17:05

5 Answers5

3

A somewhat hackish solution is to parse the env output:

newenv = {}
for line in os.popen('. /etc/rc.platform >&/dev/null; env'):
    try:
        k,v = line.strip().split('=',1)
    except:
        continue  # bad line format, skip it
    newenv[k] = v
os.environ.update(newenv)

Edit: fixed split argument, thanks to @l4mpi

Maxim Razin
  • 9,114
  • 7
  • 34
  • 33
1

(Here's a demonstration of the solution crayzeewulf described in his comment.)

If /etc/rc.platform only contains environment variables, you can read them and set them as env vars for your Python process.

Given this file:

$ cat /etc/rc.platform
FOO=bar
BAZ=123

Read and set environment variables:

>>> import os
>>> with open('/etc/rc.platform') as f:
...     for line in f:
...         k, v = line.split('=')
...         os.environ[k] = v.strip()
... 
>>> os.environ['FOO']
'bar'
>>> os.environ['BAZ']
'123'
Tom Offermann
  • 1,391
  • 12
  • 12
  • This won't work if the variables reference other variables in their declaration, e.g. `X="$Y/foo"`. Also, the script could use other shell commands (like awk, grep, etc) or builtin shell variables, which would obviously not be evaluated. – l4mpi Mar 07 '13 at 18:03
  • Good points. I guess the consensus here is that there's no easy way for this to work, except in the very simplest case that I used as an example. – Tom Offermann Mar 07 '13 at 18:11
  • I needed something similar once and ended up spawning a subshell, sourcing the script and then parsing the output of `env`... maybe I'll write up an answer after dinner. – l4mpi Mar 07 '13 at 18:16
0

Too much work for the return. Going to keep a small shell script to get all the env vars that we need and forget reading them into python.

Jason Templeman
  • 431
  • 5
  • 21
-1

Try this:

if os.path.exists ("/etc/rc.platform"):
    os.system("/etc/rc.platform")
Edouard Thiel
  • 5,878
  • 25
  • 33
  • 2
    This will not have the same effect as the shell script quoted by OP. `os.system` runs the command in a subshell and, hence, the parent process will not see any environment variables added/modified by `/etc/rc.platform`. – crayzeewulf Mar 07 '13 at 16:31
  • You cannot source sh or bash script within a python process, which doesn't know how to interpret bash language. Hence you need a subshell to run bash and interpret the script. Since it is done in a subshell, the python process won't be able to get the new env values. – Edouard Thiel Mar 07 '13 at 16:39
-1

Since source is a shell builtin, you need to set shell=True when you invoke subprocess.call

>>> import os
>>> import subprocess
>>> if os.path.isfile("/etc/rc.platform"):
...     subprocess.call("source /etc/rc.platform", shell=True)

I'm not sure what you're trying to do here, but I still wanted to mention this: /etc/rc.platform might export some shell functions to be used by other scripts in rc.d. Since these are shell functions, they would be exported only to the shell instance invoked by subprocess.call() and if you invoke another subprocess.call(), these functions would not be available since you're spawning a fresh new shell to invoke the new script.

Tuxdude
  • 47,485
  • 15
  • 109
  • 110
  • 3
    If you run the script within a subshell, it would not help, because all the environment variables settings will be discarded. – Maxim Razin Mar 07 '13 at 16:29
  • @grep - I'm aware of it, and it is not only about environment variables, even bash functions exported by `/etc/rc/platform` would be unavailable to the python script and any new shells started to invoke other related scripts from say `/etc/rc.d` – Tuxdude Mar 07 '13 at 16:36