UNIX Script - setting dynamic variables (indirect variable reference) - bash

How to set shell variables from an input file ?
hello,
I need to set dynamic variable from an .ini file in a shell script.
Assume the input file is input.ini :
var1=val1
var2=val2
var3=val3
In a script I want to set var1, var & var3 respectively to their val1, val2 & val3 to get
echo $var1
val1
echo $var2
val2
...
I've tryed :
file="input.ini"
while IFS== read -r f1 f2
do
eval dynvar=$f1
dynvar=$f2
done <"$file"
echo $var1
echo $var2
echo $var3
the echo $varx commands give no output. How can I work it out ?
thanks in advance.

source input.ini
Or
. input.ini
More info
<source | .> filename [arguments]
Execute commands from a file in the current shell.

Solved
using :
file="install.ini"
while IFS== read -r f v
do
eval "$f=$v"
done <"$file"
did the trick.

Related

Bash how to parse asscoiative array from argument?

I am trying to read a string into an associative array.
The string is being properly escaped and read into .sh file:
./myScript.sh "[\"el1\"]=\"val1\" [\"el2\"]=\"val2\""
within the script
#!/bin/bash -e
declare -A myArr=( "${1}" ) #it doesn't work either with or without quotes
All I get is:
line 2: myArr: "${1}": must use subscript when assigning associative array
Googling the error only results in "your array is not properly formatted" results.
You could read key/value pairs from variable inputs in series:
$ cat > example.bash <<'EOF'
#!/usr/bin/env bash
declare -A key_values
while true
do
key_values+=(["$1"]="$2")
shift 2
if [[ $# -eq 0 ]]
then
break
fi
done
for key in "${!key_values[#]}"
do
echo "${key} = ${key_values[$key]}"
done
EOF
$ chmod u+x example.bash
$ ./example.bash el1 val1 el2 val2
el2 = val2
el1 = val1
This should be safe no matter what the keys and values are.
Instead of caring about proper double escaping, set the variables on caller side, and use bash declare -p. That way you will always get properly escaped string.
declare -A temp=([el1]=val1 [el2]=val2)
./script.sh "$(declare -p temp)"
Then do:
# ./script.sh
# a safer version of `eval "$1"`
declare -A myarr="${1#*=}"
solution:
./test.sh "( [\"el1\"]=\"val1\" [\"el2\"]=\"val2\" )"
and within the script:
#!/bin/bash -e
declare -A myArr="${1}"
declare -p myArr
for i in "${!myArr[#]}"
do
echo "key : $i"
echo "value: ${myArr[$i]}"
done
Returns:
> ./test.sh "( [\"el1\"]=\"val1\" [\"el2\"]=\"val2\" )"
declare -A myArr=([el2]="val2" [el1]="val1" )
key : el2
value: val2
key : el1
value: val1
I can't explain why this works, or why the order changes though.
Test it yourself here

Assign the output to variable in shell script

I am new to shell scripting and i am trying to assign the output of this line to a variable but all efforts are in vain.
var2=$(cat "filename")
var1=$(echo " $var2 +3 " | bc )
var2 is properly read from the file and also the output shows the value of the sumation, but the value is not assigned to the var1
ps : Filename contains a single entry which is a number
The code worked when i tried this
var3="$("echo " $var2 +3 " |bc)"
You are missing parenthesis
var2=$(cat "file")
var3=$(( var2 + 3 ))
echo $var3
Also you can try with expr
Something like this
var2=$(cat "filename")
var3=`expr $var2 + 3`
echo $var3
Here is a good answer
HIH

From bash script to bash script in infinite loop

A very simple example of the "just run once" version of my Script:
./myscript.sh var1 "var2 with spaces" var3
#!/bin/bash
echo $1 #output: var1
echo $2 #output: var2 with spaces
echo $3 #output: var3
Working as intended!
Now I try to just start the script and enter the vars in a loop, because later I want to copy multiple datasets at once to the shell.
./myscript.sh
#!/bin/bash
while true; do
read var1 var2 var3
#input: var1 "var2 with spaces" var3
echo $var1 #output: var1
echo $var2 #output: "var2
echo $var3 #output: with spaces" var3
done
It seems read splits the input at the spaces, putting all thats left in the last var, right? Is there any better possibility to add vars in a loop? Or how do I get read to behave like I added the vars just behind the script?
And what is the English word for that kind of loop to execute one script in a loop while copying different vars to the shell? Can't google for samples if I don't know what it is called...
This reads STDIN and parses those lines as arguments with shell quoting:
# Clean input of potentially dangerous characters. If your valid input
# is restrictive, this could instead strip everything that is invalid
# s/[^a-z0-9" ]//gi
sed -ue 's/[][(){}`;$]//g' | \
while read input; do
if [ "x$input" = "x" ]; then exit; fi
eval "set -- $input"
# check argument count
if [ $(( $# % 3 )) -ne 0 ]; then
echo "Please enter 3 values at a time"
continue;
fi
echo $1
echo $2
echo $3
done
set -- $input does all of the magic. See the Bash manual page for set.
--
If no arguments follow this option, then the positional parameters are
unset. Otherwise, the positional parameters are set to the arguments,
even if some of them begin with a ‘-’.

Bash: Spliting string based on some delimiter and storing each in a variable

113050050/CS101/mysql_java.pdf
the above is my string, which is stored in a variable 'line'
line="113050050/CS101/mysql_java.pdf"
Now I want to split $line based on delimiter / and store each single part in a variable
var1=113050050
var2=CS101
var3=mysql_java.pdf
$ IFS=/ read var1 var2 var3 <<< "$line"
Results
$ echo $var1
113050050
$ echo $var2
CS101
$ echo $var3
mysql_java.pdf
This might work for you:
line="113050050/CS101/mysql_java.pdf"
var=(${line//\// })
var1=${var[0]}
var2=${var[1]}
var3=${var[2]}
as #chepner points out this will fail if spaces exist in the $line variable, a perhaps more bullet-proof solution is to use the IFS variable:
line="113050050/CS101/mysql_java.pdf" O="$IFS" IFS='/' var=($line) IFS="$O"

shell scripting string replace using shell variables

This is my very basic script:
temp=hello
while read line;
do
echo ${line}
done
However, ${line} will itself consist of "value of temp = ${temp}"
I want my script to echo "value of temp is hello". I've tried doing many things, even
echo `echo ${line}`
but each time it always just prints "value of temp is ${temp}"
I hope this question is clear. THanks!
What about this?
temp=hello
while read line; do
echo "Value of temp = `eval echo ${line}`"
done
Then in the console just type:
${temp}
Well, I have solutions with eval, but using eval is mauvais ton, actually.
$> cat 7627845.sh
#!/bin/bash
temp=hello
cat file_with_values.log | while read line;
do
eval echo "${line}"
done
$> cat file_with_values.log
value of temp = ${temp}
$> ./7627845.sh
value of temp = hello

Resources