0

I'm using bash and have a file called x.config that contains the following:

MY_VAR=Something1
ANOTHER=Something2

To load these as environment variables I just use source:

$ source x.config

But this doesn't work if MY_VAR is called MY-VAR:

MY-VAR=Something1
ANOTHER=Something2

If I do the same thing I get:

x.config:1: command not found: MY-VAR=Something1

I've tried escaping - and a lot of other things but I'm stuck. Does anyone know a workaround for this?

Johan
  • 37,479
  • 32
  • 149
  • 237
  • 3
    Variable names cannot contain hyphen – anubhava Feb 02 '16 at 11:02
  • Why can't you use underscore ? – 123 Feb 02 '16 at 11:03
  • Well I know you can escape it if you do env 'MY-VAR=..' so I suppose there must be a workaround? – Johan Feb 02 '16 at 11:03
  • @123 Because I need to pass it into an application that requires "-" – Johan Feb 02 '16 at 11:04
  • @Johan What? You don't/can't pass the variable name to other applications... – 123 Feb 02 '16 at 11:09
  • 1
    @Johan `Well I know you can escape it if you do env 'MY-VAR=..' ` No you can't – 123 Feb 02 '16 at 11:15
  • @123 Sorry, what I mean is that the application reads its config from the environment (i.e. the defined environment variables) and it requires hyphen in some of the configuration names. This works for example when using when I use docker or docker-compose to read a set of predefined environment variables from a file. – Johan Feb 02 '16 at 11:16
  • 3
    @Johan You can't do it, change your application to use valid env variables. – 123 Feb 02 '16 at 11:18
  • hm. I can set a variable containing a dash from python... – Karoly Horvath Feb 02 '16 at 11:32
  • Possible duplicate of http://stackoverflow.com/questions/2821043/allowed-characters-in-linux-environment-variable-names – tripleee Feb 02 '16 at 11:41
  • @123 I take your word for it. It would be interesting to know you docker-compose manage to do this though? But that's another question I suppose. – Johan Feb 02 '16 at 11:58
  • 1
    @123 `env 'MY-VAR=3' bash` will add the variable to the environment; it's just not exposed as a shell environment variable. It will be passed to any child processes which may be able to use it. – chepner Feb 02 '16 at 15:09
  • @chepner So it does... – 123 Feb 02 '16 at 15:25

2 Answers2

3

A pure bash workaround that might work for you is to re-run the script using env to set the environment. Add this to the beginning of your script.

if [[ ! -v myscript_env_set ]]; then
    export myscript_env_set=1
    readarray -t newenv < x.config
    exec env "${newenv[@]}" "$0" "$@"
fi

# rest of the script here

This assumes that x.config doesn't contain anything except variable assignments. If myscript_env_set is not in the current environment, put it there so that the next invocation skips this block. Then read the assignments into an array to pass to env. Using exec replaces the current process with another invocation of the script, but with the desired variables in the environment.

chepner
  • 497,756
  • 71
  • 530
  • 681
1

A dash (-) in an environment variable is not portable, and as you noticed, will cause a lot of problems. You can't set these from bash. Fix the application you want to invoke.

That being said, if you can't change the target app, you can do this from python:

#!/usr/bin/python

import os

with open('x.config') as f:
    for line in f:
        name, value = line.strip().split('=')
        os.environ[name] = value

os.system('/path/to/your/app')

This is a very simplistic config reader, and for a more complex syntax you might want to use ConfigParser.

Community
  • 1
  • 1
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176