Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

i have a text file variables.txt where i store my variables

host=/srv/www/vhosts/hosting

index=$host/index.php

as you see the second variables depends on the first one.

i also have a script file to load these variables

f=~/variables.txt
for line in $(cat $f)
do
export $line
done

when i execute the script file, my first variable gets loaded, while the second doesn't:

bash: $host/index.php: No such file or directory

it's because after loading the first variable host, it doesn't remember its value to use for setting the second variable index.

So how to solve this problem? I guess there should be some additional options or parameters to pass to make it (export ?) remember the set variable value in a for loop.

share|improve this question

4 Answers 4

up vote 3 down vote accepted

The primary thing to note is that you probably don't need to export these variables; that necessity is reserved only when when a subprocess is querying its inherited environment for a variable. Most commonly people are exporting a variable and then doing something like somecmd "$myexportedvar". Your shell is expanding $myexportedvar before somecmd ever sees it.

If you really do need to export these for a subprocess to pull from its environment:

while IFS= read -r line; do
  if [[ $line == *=* && $line != #* ]]; then
    IFS== read -r var val <<<"$line"
    printf -v "$var" '%s' "$val"
    export "$var"
  fi
done < "$HOME/variables.txt"

this loop checks that the line is an assignment (kinda) and that the first character is not a comment hash. makes the effort a little more robust, but just barely. see the two options below instead, for handling this more carefully.

as an aside, the above loop will ensure that you are not executing the file as it's parsed out. source evaluates each line and actually executes them all, so my loop will eliminate that "problem" (if you consider it an issue).

Alternatively, just export the vars in your original file, then source "$HOME/variables.txt" and the work is already done.

you may want to just use set -a; . "$HOME"/variables.txt; set +a. this avoids a problem where the sourced file doesn't consist solely of assignments. the parsing loop above can result in false-positives. read help set to understand what it's doing.

Also, Don't Read Lines With For and Use More Quotes

share|improve this answer

you have a easier way to perform that.

cat vars
host=/srv/www/vhosts/hosting
index=$host/index.php

my test script:

#!/bin/bash
. ./vars
echo $host
echo $index

Execution

./printvars.sh
/srv/www/vhosts/hosting
/srv/www/vhosts/hosting/index.php

Basically the . ./vars executes the files and loads the variables.

share|improve this answer
    
i know, but my actual file is too big and filled up with variable definitions, that i want to export with a for loop. i don't want to write export command on each line in my variables.txt file and then to source it, i want to do it with for loop instead. –  easl Jul 23 '13 at 7:41
2  
The command sed 's/^/export /' vars writes "export" at the beginning of each line in vars. This is unix, you're trying to do it the hard way. –  msw Jul 23 '13 at 18:56

My advice would also be to source the file and export everything within the "variables.txt" file. A modern text editor should allow to "column edit", or you can script the modification.

However, I managed to answer your question with this script :

#!/bin/sh

f=./variables.txt
source ${f}
for vname in $(cut -f1 -d'=' ${f})
do
    export ${vname}
done

The difference is that I source the variables.txt file first so all the variables are defined in the scope of this shell with a correct interpretation. Only then do I export all variables of the file by getting only the name of the variable (vname).

On a side note, you should protect your variables with ${}.

share|improve this answer
    
as an aside to your aside, one should only use curly braces for two things: disambiguation between a variable's name and other coinjoined text "${var}string", and alternatively for Parameter Expansions "${name:-default}". "Protecting" variables is to be done with double-quotes. Use More Quotes –  Josh McGee Jul 23 '13 at 19:12
    
Nice ! Thanks for the link. –  Louis Carrese Jul 24 '13 at 7:49

You can do it in two steps:

. ./vars
while read line; do
    export $(printf "%s" "$line" | grep = | cut -d= -f 1)
done < vars

or just one

while read line; do
   eval export "$line"
done < vars
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.