Ok so I was wondering if it is possible to save like a variable in bash. I am writing a script where you build like farms and mines and I was just wondering if it is possible to bring back those variables even after I stopped the program and then got back on. So lets say I have built 4 farms farms would be farm=4, can I bring this variable back somehow? I know how to make a page that you can make a high scores list on (Which I did for a guessing game.), but this I don't know if it is possible in bash.
You can write everything in a file in that format:
farm=4
myname=gniourf
And then source that file:
#!/bin/bash
# Recover the saved states:
source file_where_i_saved_my_stuff
# Now you can recover all your variables!
echo "$farm"
echo "$myname"
Since you want to know how you can save your variables, here's a quick hint, with a lot of stuff that hasn't been given in the other answer.
Alright, so you want to save some variables in a file, and be able to later source this file to recover the value of these variables. Of course, you'll have a lot of variables, and you don't want to explicitly write down the list of all the variables you'll have to save, which is error prone and retarded. I mean, nobody wants to do the following:
cat <<EOF > file_where_i_saved_my_stuff
variable1=$variable1
variable2=$variable2
...
variable1000000=$variable1000000
EOF
In fact, you don't want to do this at all for many reasons. Now, I'll address the solution:
The method relies on this stupid thing (together with good bash practice and knowledge): name all the variables you want to save using a prefix, e.g., variable_i_want_to_save_
, so that you'll have variables like variable_i_want_to_save_number_of_farms
and variable_i_want_to_save_color_of_granny_dress
and so on. Do not use this prefix with variables you don't want to save.
bash has a wonderful thing: you can get the name of all variables that start with a certain prefix like so:
"${!prefix@}"
This will expand to a list of all known variables that start with prefix prefix
.
Hence, in our case,
for i in "${!variable_i_want_to_save_@}"; do
will loop through the name of all variables that are prefixed by our wonderful prefix. Isn't that great?
If I am in the following situation:
a=1
b=2
variablename="a"
how do I get the value of the variable the name of which is the value of the variable variablename
? Easy, use the "${!variablename}"
construct. Look:
$ a=1
$ b=2
$ variablename=a
$ echo "${!variablename}"
1
The ${!prefix@}
and ${!variablename}
expansions are explained in the Shell Parameter Expansion section of the Bash reference (you'll have to scroll down a bit to get there).
Then you're good for a broken solution to save your variables in a file, like so:
save_data_to_file() {
for i in "${variable_i_want_to_save_@}"; do
echo "$i=${!i}"
done > file_where_i_saved_my_stuff
}
This is really efficient and cool, but really broken if you have spaces or junk characters of any sort in your variables (which can (and should) appear). Oh dear.
The good thing for you is that bash has this wonderful printf
command with its amazing format specification %q
that will
quote the argument in a way that can be reused as shell input
(I got this from help printf
). It's amazing, it's absolutely fantastic, just try it:
$ a=$'bonjour les amis !\ncomment ça va ?'
$ # You see, variable a has a lot of stupid characters:
$ echo "$a"
bonjour les amis !
comment ça va ?
$ # and printf does a wonderful job:
$ printf '%s=%q\n' a "$a"
a=$'bonjour les amis!\ncomment \303\247a va ?'
You couldn't dream of something as good as this. Or maybe you could, but please just admit it's awesome!
So, here you are with your wonderful way to save your variables in a file:
save_data_to_file() {
for i in "${!variable_i_want_to_save_@}"; do
printf '%s=%q\n' "$i" "${!i}"
done > file_where_i_saved_my_stuff
}
Note that sourcing an external file like this leads to obvious security issues, so make sure you only use this method with care!
You can save all needed variables in a file (using here-doc):
cat<<EOF>/path/to/file
var1="$var1"
var2="$var2"
EOF
and to recreate your previous environment :
source /path/to/file
or
. /path/to/file
EXPLANATIONS
source
command is the top of your script after the shebang
Help said :
$ LANG=C help source
source: source filename [arguments] Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The entries in $PATH are used to find the directory containing FILENAME. If any ARGUMENTS are supplied, they become the positional parameters when FILENAME is executed. Exit Status: Returns the status of the last command executed in FILENAME; fails if FILENAME cannot be read.
NOTE
if you want for some reasons to dynamically generate the files with pattern matching on variable names :
printf '%q\n' $(set | grep "suffix=") > save_file
printf '%q\n' $(set | grep "^prefix") > save_file
Thanks gniourf_gniourf for printf
trick.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With