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

5
  • 3
    You will have to parse /etc/rc.platform, extract environment variable names and values, and update os.environ accordingly. Commented Mar 7, 2013 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. Commented Mar 7, 2013 at 16:35
  • 1
    I suggest porting /etc/rc.platform to Python as well, since . is very similar to import. Commented Mar 7, 2013 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. Commented Mar 7, 2013 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. Commented Mar 7, 2013 at 17:05

5 Answers 5

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

Sign up to request clarification or add additional context in comments.

Comments

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'

3 Comments

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.
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.
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.
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.

Comments

-1

Try this:

if os.path.exists ("/etc/rc.platform"):
    os.system("/etc/rc.platform")

2 Comments

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.
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.
-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.

2 Comments

If you run the script within a subshell, it would not help, because all the environment variables settings will be discarded.
@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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.