好的,所以我想知道是否可以像bash中的变量一样保存。我正在写一个脚本,你可以像农场和矿山一样构建,我只是想知道,即使在我停止程序并重新开始之后,是否有可能恢复这些变量。所以,假设我已经构建了4个农场,农场将为farm=4,我能以某种方式恢复这个变量吗?我知道如何制作一个页面,你可以在上面列出高分列表(这是我在猜谜游戏中做的),但我不知道这在bash中是否可行。
您可以用以下格式在文件中写入所有内容:
farm=4
myname=gniourf
然后获取该文件:
#!/bin/bash
# Recover the saved states:
source file_where_i_saved_my_stuff
# Now you can recover all your variables!
echo "$farm"
echo "$myname"
编辑
既然您想知道如何保存变量,这里有一个快速提示,其中包含许多其他答案中没有给出的内容。
好吧,所以你想把一些变量保存在一个文件中,然后能够获取这个文件的源代码来恢复这些变量的值。当然,你会有很多变量,而且你不想明确地写下你必须保存的所有变量的列表,这是容易出错和延迟的。我的意思是,没有人想做以下事情:
cat <<EOF > file_where_i_saved_my_stuff
variable1=$variable1
variable2=$variable2
...
variable1000000=$variable1000000
EOF
事实上,你根本不想这么做,原因有很多。现在,我将介绍解决方案:
该方法依赖于这件愚蠢的事情(加上良好的bash实践和知识):使用前缀命名所有要保存的变量,例如variable_i_want_to_save_
,这样你就有了variable_i_want_to_save_number_of_farms
和variable_i_want_to_save_color_of_granny_dress
等变量。不要将此前缀与不想保存的变量一起使用。
聪明的事情#1
bash有一个很棒的功能:您可以获得所有以某个前缀开头的变量的名称,比如:
"${!prefix@}"
这将扩展到以前缀prefix
开头的所有已知变量的列表。
因此,在我们的案例中,
for i in "${!variable_i_want_to_save_@}"; do
将循环遍历以我们出色的前缀为前缀的所有变量的名称。这不是很棒吗?
聪明的事情#2
如果我处于以下情况:
a=1
b=2
variablename="a"
如何获取名称为变量variablename
的值的变量的值?简单,使用"${!variablename}"
结构。外观:
$ a=1
$ b=2
$ variablename=a
$ echo "${!variablename}"
1
${!prefix@}
和${!variablename}
展开在Bash参考的外壳参数展开部分中进行了解释(您必须向下滚动一点才能到达)。
(坏的)解决方案
然后你就可以用一个坏的解决方案将变量保存在一个文件中,比如:
save_data_to_file() {
for i in "${variable_i_want_to_save_@}"; do
echo "$i=${!i}"
done > file_where_i_saved_my_stuff
}
这真的很有效,也很酷,但如果你的变量中有空格或任何类型的垃圾字符(它们可以(也应该)出现),那就真的坏了。哦,天哪。
解决方案
对你来说,好的事情是bash有这个很棒的printf
命令,它有令人惊叹的格式规范%q
,它将
以一种可以重新用作shell输入的方式引用参数
(我是从help printf
得到的)。这太神奇了,绝对棒极了,试试吧:
$ 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=%qn' a "$a"
a=$'bonjour les amis!ncomment 303247a va ?'
你做梦也想不到这么好的东西。也许你可以,但请承认这太棒了!
因此,现在您可以用一种奇妙的方法将变量保存在一个文件中:
save_data_to_file() {
for i in "${!variable_i_want_to_save_@}"; do
printf '%s=%qn' "$i" "${!i}"
done > file_where_i_saved_my_stuff
}
请注意,这样的外部文件会导致明显的安全问题,因此请务必小心使用此方法!
您可以将所有需要的变量保存在一个文件中(使用此处的文档):
cat<<EOF>/path/to/file
var1="$var1"
var2="$var2"
EOF
并重新创建您以前的环境:
source /path/to/file
或
. /path/to/file
解释
- 在这里放置文档的位置取决于您的代码,如果您不必通过示例将变量保存在循环中,则可以是最后一行
- 放置
source
命令的位置是shebang之后脚本的顶部
帮助说:
$ LANG=C help source
源:源文件名[参数]从当前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.
注意
如果出于某些原因,您希望动态生成具有变量名模式匹配的文件:
- 后缀:
printf '%qn' $(set | grep "suffix=") > save_file
- 按前缀:
printf '%qn' $(set | grep "^prefix") > save_file
感谢gniourf_gniourf的printf
技巧。