在bash中保存数据



好的,所以我想知道是否可以像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_farmsvariable_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技巧。

相关内容

  • 没有找到相关文章

最新更新