HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Setting global environment vars from Python or Bash

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
globalvarsenvironmentsettingpythonfrombash

Problem

#!/usr/bin/env python

from os import environ, path, name as os_name, getuid
from sys import exit
from fileinput import input

update_environ = lambda: environ.update(dict(env.split('=')
                                        for env in
                                        open('/etc/environment', 'r').readlines()))

if os_name != 'nt' and getuid() != 0:
    print "Rerun {0} as `sudo`".format(__file__)
    exit(1)

def custom_vars(e_vars):
    if not path.isfile('custom_vars.txt'):
        return e_vars
    with open('custom_vars.txt', 'r') as f:
        for line in f.readline():
            var = line.split()
            e_vars[var[0]] = var[1]

def append_environment(e_vars):
    for line in input('/etc/environment', inplace=True):
        var, _, val = line.partition('=')
        nline = '{var}={val}'.format(var=var, val=e_vars.pop(var, val))
        if nline and nline != '=' and nline != '\n' and nline != '=\n':
            print nline  # inplace editing

    if e_vars:
        lines = filter(lambda l: l != '=\n' and nline != '\n',
                       ['{var}={val}\n'.format(var=k, val=e_vars[k])
                        for k in e_vars])
        with open('/etc/environment', 'a') as f:
            f.writelines(lines)

if __name__ == '__main__':
    environment_vars = {'NOM_REPOS': path.join(path.expanduser("~"), 'NOM'),
                        'NOM_API': path.join('/var', 'www')}

    environment_vars = custom_vars(environment_vars)
    append_environment(environment_vars)


I have written a similar script in Bash; with identical functionality:

``
#!/usr/bin/env bash

sudo sed -i "/^NOM*/d" /etc/environment
for i in
env | grep NOM | cut -f1 -d=`; do
unset "$i";
done

function set_var()
{
VAR="$1"
VAL="$2"

sudo sed -i "/^$VAR/d" /etc/environment
printf "$VAR=$VAL\n" | sudo tee -a /etc/environment > /dev/null

# make the variable available for use in this script and custom_env_vars.sh
export "$VAR=$VAL"
}

set_var NOM_

Solution

env | grep '^NOM' would more exactly align with the sed command.

ensure you're exactly matching the variable name:

sudo sed -i "/^$VAR=/d" /etc/environment
# .................^


Use %-formatters for printf:

printf '%s="%s"\n" "$VAR" "$VAL"


In the function, use local to limit the scope of VAR and VAL

had another thought about that function. Change

sudo sed -i "/^$VAR/d" /etc/environment
printf "$VAR=$VAL\n" | sudo tee -a /etc/environment > /dev/null


to

tmpfile=$(mktemp)
grep -v "^$VAR=" /etc/environment > $tmpfile
echo "$VAR=$VAL" >> $tmpfile
sudo mv $tmpfile /etc/environment


That minimized any possibility that the /etc/environment file contains "invalid" data -- it overwrites the previous good file with the new good file all at once.

Code Snippets

sudo sed -i "/^$VAR=/d" /etc/environment
# .................^
printf '%s="%s"\n" "$VAR" "$VAL"
sudo sed -i "/^$VAR/d" /etc/environment
printf "$VAR=$VAL\n" | sudo tee -a /etc/environment > /dev/null
tmpfile=$(mktemp)
grep -v "^$VAR=" /etc/environment > $tmpfile
echo "$VAR=$VAL" >> $tmpfile
sudo mv $tmpfile /etc/environment

Context

StackExchange Code Review Q#46165, answer score: 5

Revisions (0)

No revisions yet.