Read variables from a file and then export it.

Hi
I want to read variables from one file and then set it as environment variable;
The text file is test.txt which contains
SPEED:1000
IP:172.26.126.11
My code is:

while read line; do
var1=`echo $line | awk 'BEGIN {FS=":"} { print $1 }'`
echo $var1
var2=`echo $line | awk 'BEGIN {FS=":"} { print $2 }'`
echo $var2
export $var1=$var2
echo $var1
done < test.txt

But it does not set SPEED=1000 or IP:172.26.126.11
It gives me output :
SPEED
1000
SPEED
IP
172.26.126.11
IP
Please help me to export those variables.
Thanks.

eval export $var1=$var2
1 Like

You could try something like:-

`cat test.txt | tr ":" "="`

This will change the colon character to be an equal sign and then execure the resulting statement. This must come with a warning that you must be absolutely certain of the integrity of the process creating the file. Consider that the following input file would cause damaging results.

SPEED:1000
IP:172.26.126.11
rm -r /

The process is using cat, I know but I can seem to get tr to take an input file. It would be far better if the source file could be written with the equal already in it and then you would simply:-

. test.txt

Robin
Liverpool/Blackburn
UK

1 Like

Thanks alot :slight_smile:

eval export $var1=$var2

It worked !!!

Again, I would caution you that you must be certain that no rogue entries appear that could destroy your system. I wouldn't say that eval is evil in itself, but it does introduce risks.

Robin

You can avoid the inefficient and unnecessary command substitution pipelines by using IFS:

while IFS=: read name value; do
    eval export $name=$value

Your main point stands, but your specific example is harmless. While eval'ing untrusted input is a massive risk, rm -r / leading to export rm -r /= won't cause any damage. I would expect nothing more than a harmless syntax error message. Worst case, perhaps an empty variable named rm is exported into the environment. However, foo:bar; rm -r / leading to export foo=bar; rm -r / will cause grief.

With regard to tr, it doesn't take file arguments. It's a simple filter that reads from stdin and writes to stdout. However, you can read a file without using cat; just use redirection.

tr ... < file

Sourcing a file is simpler and cleaner than a while-read-eval loop, but it's no safer. If the input is untrusted, eval and sourcing both execute it.

If the shell supports process substitution, the file's contents can be transformed in transit:

. <(sed 's/:/=/; s/^/export /')

Regards,
Alister

2 Likes

Yes. It is really helpful.

while IFS=: read name value; do    
 eval export $name=$value
eval export `tr : = <test.txt`
2 Likes

Yes MadeInGermany,

That looks like the neatest solution :cool: - with the same caution, or course.

Thanks for this :b:

Robin