Write multiple variables in a file to can read them later - bash

It's there a simple way to write multiple variables into a file and later to read them?
For example to write the next variables into a file:
test=1
b=3
a=earth
echo "test=1" > variables.prop
echo "b=3" >> variables.prop
echo "a=earth" >> variables.prop
And somehow to return the value of specified variable and use it.
Like
*command to import the variable "test" from the text file*
echo $test
*command to import the variable "b" from the text file*
echo $b
and the expected output for "test" should be "1" and for "b" to be "3".

Create variables.prop exactly as you're doing, then use the . command (AKA source) to read it in.
. variables.prop
echo "$test"
echo "$b"

Related

Update value of a variable from a function in shell script

a=master
b="9876"
secondfunction(){
a=develop
b="1234"
echo "Inside second function"
echo $1
echo $2
}
secondfunction $a $b
In the above shell script echo command prints a=master and b=9876. I want to print a=develop and b =1234.
Here you are indeed changing the value of a and b like you want to, To see this you can print out a and b after the function has been called
echo $a $b
secondfunction $a $b
echo $a $b
and you can see that the output will be master 9876 for the first one and develop 1234 for the second one. Just that you cannot change the value of $1 and $2 by changing the values of a and b. For that you'll need to explicitly change them using set like #william has pointed out.
Also variables in shell script are globally scoped unless explicitly mentioned otherwise. So if all you want to do is change the values of those variables, you need not explicitly pass them into the function as arguments.
a=master
b="9876"
secondfunction(){
a=develop
b="1234"
echo "Inside second function"
echo $a
echo $b
}
secondfunction
will also work

How to import a config file variable, but use a different separator?

First, source and . are not working as I'm using a different kind of separator, which is something like.
I have tried several methods I can google, but didn't have any luck so far.
I managed to print out all the variables and values correctly, but I can't store it as a variable in this bash process.
What I want:
At end of the bash process when I "echo $HUA_IP:"
it should give me "192.168.0.1" as per the config.cf file.
File config.cf:
"HUA_PASSWORD": "admin",
"HUA_IP": "192.168.0.1"
While my bash file is:
#!/bin/bash
configFile="/opt/config.cf"
# config="`cat $configFile`"
# echo $config
# source $configFile
# echo $var1
# conf="";
while read var value
do
# export "$var"="$value"
var="${var%:*}"
var="${var//\"/}"
var="${var//[\}\{]/}"
value="${value//\"/}"
value="${value//,/}"
# echo "var :'"$var"'"
# echo "value :'"$value"'"
if [ !$var = "" ]
then
# "$var"="$value"
# eval $var=$value
export "$var"="$value"
fi
done < $configFile
echo $HUA_IP:
Try:
while read -r line; do
line=${line//\"/}
declare -x "${line/: /=}"
done<config.cf
echo "$HUA_IP"
When this code is run, the output is:
192.168.0.1
How it works
The key here is that declare, which is a bash builtin, allows you to use a bash variable to create and assign another variable. As a simple example:
$ x="a=b"; declare -x "$x"; echo "$a"
b
Now, let's apply this to your input file:
while read -r line; do
This starts a loop reading one line of input at a time.
line=${line//\"/}
This removes all double-quotes from the input line.
declare -x "${line/: /=}"
This replaces : with = in line and then creates a variable using declare.
The -x option tells bash to export the variable that is declared.
done <config.cf
This tells the loop to get its stdin from config.cf.
Your code, even if it could be not the best approach, is working if you change your if condition. The correct way is:
#...
if [ ! -z $var ]
then
# "$var"="$value"
# eval $var=$value
export "$var"="$value"
fi

Bash appending extra characters to variable?

I'm trying to store values in variables and trying to echo result to a file. But when it's adding two variables and echoing it to a file, extra characters are being added to the output file. This is happening in docker container, Can some one please help...
IFS=" "
#while read line
while read c s e
do
echo $c $s $e
first=$(echo "PER_${s}_${e}")
#echo -n $first
second=$(echo "/IPD_${c}")
#echo $second
echo $first$second >> /mnt/resource/step2/messages.txt
done < /mnt/resource/step2/job_control/Categories.txt
Categories.txt contains :
129490 201515 201540
I'm getting the output as :
PER__/IPD_PER_201515_201540/IPD_12949029490
But it should be like:
PER_201515_201540/IPD_129490
I can't reproduce the problem, but your code is more complicated than it needs to be.
while IFS=" " read c s e; do
first="PER_${s}_${e}"
second="/IPD_${c}"
echo "$first$second" >> /mnt/resource/step2/messages.txt
done < /mnt/resource/step2/job_control/Categories.txt

How to use a text file for multiple variable in bash

I want to make an bash script for things I use much and for easy access of things but I want to make an firstrun setup that saves the typed paths to programs or commands in a txt file. But how can I do that. And how can I include the lines of the text file to multiple variables?
After a lot of testing I could use the 2 anwsers given. I need to store a variable directly to a textfile and not asking a user for his details and then stores that to a file
So I want it to be like this
if [[ -d "/home/$(whoami)/.minecraft" && ! -L "/home/$(whoami)/.minecraft" ]] ; then
echo "Minecraft found"
minecraft="/home/$(whoami)/Desktop/shortcuts/Minecraft.jar" > safetofile
# This ^ needs to be stored on a line in the textfile
else
echo "No Minecraft found"
fi
if [[ -d "/home/$(whoami)/.technic" && ! -L "/home/$(whoami)/.technic" ]]; then
echo "Technic found"
technic="/home/$(whoami)/Desktop/shortcuts/TechnicLauncher.jar" > safetofile
# This ^ also needs to be stored on an other line in the textfile
else
echo "No Technic found"
fi
I really want to have an anwser to this because I want to script bash. I already experience in bash scripting.
Here's an example:
#!/bin/bash
if [[ -f ~/.myname ]]
then
name=$(< ~/.myname)
else
echo "First time setup. Please enter your name:"
read name
echo "$name" > ~/.myname
fi
echo "Hello $name!"
The first time this script is run, it will ask the user for their name and save it. The next time, it will load the name from the file instead of asking.
#!/bin/bash
# file to save the vars
init_file=~/.init_vars.txt
# save_to_file - subroutine to read var and save to file
# first arg is the var, assumes init_file already exists
save_to_file()
{
echo "Enter $1:"
read val
# check if val has any spaces in them, you will need to quote them if so
case "$val" in
*\ *)
# quote with double quotes before saving to init_file
echo "$1=\"$val\"" >> $init_file
;;
*)
# save var=val to file
echo "$1=$val" >> $init_file
;;
esac
}
if [[ ! -f $init_file ]]
then
# init_file doesnt exist, this will come here only once
# create an empty init_file
touch $init_file
# vars to be read and saved in file, modify accordingly
for var in "name" "age" "country"
do
# call subroutine
save_to_file "$var"
done
fi
# init_file now has three entries,
# name=val1
# age=val2
# country=val3
# source the init_file which will read and execute commands from init_file,
# which set the three variables
. ${init_file}
# echo to make sure it is working
echo $name $age $country

Bash function parameter assignment to read a file (list) and write a file (array)

I am trying to write a bash function I can call regularly from within a larger set of scripts. I want to pass this function the name of a file containing a plain list of text strings:
blue
red
green
... and have the function write out these strings to a different file (the name of which is also passed as parameter to the function) in bash-compatible array format:
[Bb]lue [Rr]ed [Gg]reen
I can't get the function to (internally) recognise the name of the output file being passed. It throws an "ambiguous redirect" error and then a bunch of "No such file or directory" errors after that. It is however processing the input file OK. The problem appears be how I am assigning the parameter to a local string in the function. Unfortunately I have changed the loc_out= line in the function so many times that I can no longer recall all the forms I have tried. Hopefully the example is clear, if not best practise:
process_list () {
# assign input file name to local string
loc_in=(${1});
# assign output file name to local string
loc_out=($(<${2})); # this is not right
while read line
do
echo "loc_out before: $loc_out";
echo "loc_in term: $line";
item_length=${#line};
# loop until end of string
for (( i=0; i<$item_length; i++ ));
do
echo "char $i of $line: ${line:$i:1}";
# write out opening bracket and capital
if [ ${i} -eq 0 ]; then
echo -e "[" >> $loc_out;
echo -e ${line:$i:1} | tr '[:lower:]' '[:upper:]' >> "${loc_out}";
fi;
# write out current letter
echo -e ${line:$i:1} >> "${loc_out}";
# write out closing bracket
if [ ${i} -eq 0 ]; then
echo -e "]" >> "${loc_out}";
fi;
done;
# write out trailing space
echo -e " " >> "${loc_out}";
# check the output file
echo "loc_out after: ${loc_out}";
done < $loc_in;
}
f_in="/path/to/colour_list.txt";
f_out="/path/to/colour_array.txt";
echo "loc_in (outside function): ${loc_in}";
echo "loc_out (outside function): ${loc_out}";
process_list $f_in $f_out;
Any assistance on what I am doing wrong would be much appreciated.
Change:
loc_out=($(<${2})); # this is not right
To this:
loc_out=(${2}); # this should be right
You want in that line just the file name.
Hopefully this will solve your problem.
EDIT:
Besides you could/should write this:
loc_in=${1};
loc_out=${2};
You do not need parantheses, as far as I understand.

Resources