I want to read the following variables from a data file in bash.
#/tmp/input.dat
$machie=1234-567*890ABC
$action=REPLACE
$location=test_location
Thanks for your help.
Tas
#!/usr/bin/env bash
case $BASH_VERSION in
''|[0-3].*) echo "ERROR: Bash 4.0 or newer is required" >&2; exit 1;;
esac
# read input filename from command line, default to "/tmp/input.dat"
input_file=${1:-/tmp/input.dat}
declare -A vars=()
while IFS= read -r line; do
[[ $line = "#"* ]] && continue # Skip comments in input
[[ $line = *=* ]] || continue # Skip lines not containing an "="
line=${line#'$'} # strip leading "$"
key=${line%%=*} # remove everything after first "=" to get key
value=${line#*=} # remove everything before first "=" to get value
vars[$key]=$value # add key/value pair to associative array
done <"$input_file"
# print the variables we read for debugging purposes
declare -p vars >&2
echo "Operation is ${vars[action]}; location is ${vars[location]}" >&2
See:
[1] - Note that if you aren't going to use associative arrays, as suggested in this answer, for security reasons it's best to use a prefixed namespace: printf -v "var_$key" %s "$value" -- generating variable names you would dereference as $var_action or $var_location -- is much safer than printf -v "$key" %s "$value", as the former ensures that your data file can't overwrite a security-critical environment variable such as PATH or LD_PRELOAD, by way of causing such attempts to harmlessly set $var_PATH or $var_LD_PRELOAD.
$s, your input file would be a valid shell script, so you couldsource /tmp/input.datto execute it in the current interpreter. Of course, this means you need to trust its contents to not do anything malicious (even unintentionally!) when parsed in this way; it would be safer to generate it with code that knows how to do proper shell escaping if it's not hand-written by a human who knows the pertinent rules.