在bash中保存数据?
好的,我想知道是否可以像bash中的变量一样保存。我正在写一个脚本,在那里你可以像农场和矿山一样构建,我只是想知道,即使在我停止程序,然后重新开始之后,是否有可能恢复这些变量。假设我已经建立了4个农场,农场将是farm=4,我能把这个变量带回来吗?我知道如何创建一个页面,您可以在上面创建一个高分列表(这是我在猜谜游戏中做的),但我不知道在bash中是否可以做到这一点。您可以将所有需要的变量保存在一个文件中(使用here doc): 或 解释在bash中保存数据?,bash,shell,Bash,Shell,好的,我想知道是否可以像bash中的变量一样保存。我正在写一个脚本,在那里你可以像农场和矿山一样构建,我只是想知道,即使在我停止程序,然后重新开始之后,是否有可能恢复这些变量。假设我已经建立了4个农场,农场将是farm=4,我能把这个变量带回来吗?我知道如何创建一个页面,您可以在上面创建一个高分列表(这是我在猜谜游戏中做的),但我不知道在bash中是否可以做到这一点。您可以将所有需要的变量保存在一个文件中(使用here doc): 或 解释 放置here文档的位置取决于您的代码,如果您不必通过
- 放置here文档的位置取决于您的代码,如果您不必通过示例将变量保存在循环中,则可以是最后一行
- 放置
命令的位置是shebang之后脚本的顶部source
$ 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'%q\n'$(set | grep“suffix=“)>save_文件
- 按前缀:
printf“%q\n”$(设置| grep“^prefix”)>保存文件
感谢gniourf\u gniourf的
printf
技巧。您可以将所有内容以该格式写入文件:
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
这将扩展到以prefixprefix
开头的所有已知变量的列表
因此,在我们的情况下
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}
扩展(必须向下滚动一点才能到达)
(破)解
然后,您可以使用一个已损坏的解决方案将变量保存到文件中,如下所示:
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输入
(这是我从帮助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=%q\n' a "$a"
a=$'bonjour les amis!\ncomment \303\247a va ?'
你做梦也想不到有这么好的东西。也许你可以,但请承认这太棒了
因此,下面是将变量保存到文件中的绝妙方法:
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
}
请注意,像这样寻找外部文件会导致明显的安全问题,因此请确保您只小心使用此方法为什么不考虑在文件中写入这些值呢?Bash变量对于你正在做的事情来说似乎是个坏主意,所以我只是把第二件事放在脚本和文件的顶部,放在它所在的位置的名称上,对吗?这就像是cat/path/to/savefilename,这就像是一个save按钮,对吗?然后加载第二个。我这样做对吗?好的,我要说的是我用猫。。。作为保存文件。然后我使用source/path/to/file作为加载程序,这是我从这个添加的注释中得到的,用于前缀或后缀变量的模式匹配。我现在已经测试了它,我现在理解了它,所以非常感谢您,我以后可能也会使用它。在我的解决方案中添加了您的printf技巧。您的参数扩展不能处理后缀AFAIK,也不能处理regex。是的,但我还需要一个save命令,这是我一直在寻找的一些伟大的技术,但是(a)
“${prefix@}”
应该是“${!prefix@}”
(在本文的其余部分如此),以及(b)值得指出的是,源化整个文件会带来安全风险,因为它不仅会执行变量定义,还会执行任何存在的命令。
$ a=1
$ b=2
$ variablename=a
$ echo "${!variablename}"
1
save_data_to_file() {
for i in "${variable_i_want_to_save_@}"; do
echo "$i=${!i}"
done > file_where_i_saved_my_stuff
}
$ 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 ?'
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
}