Setting a variable whose value depends on another variable

7,391

Solution 1

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

Solution 2

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.

Solution 3

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:
7,391

Related videos on Youtube

easl
Author by

easl

Updated on September 18, 2022

Comments

  • easl
    easl over 1 year

    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.

  • easl
    easl almost 11 years
    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.
  • msw
    msw almost 11 years
    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.
  • Josh McGee
    Josh McGee almost 11 years
    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