Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在bash中保存数据?_Bash_Shell - Fatal编程技术网

在bash中保存数据?

在bash中保存数据?,bash,shell,Bash,Shell,好的,我想知道是否可以像bash中的变量一样保存。我正在写一个脚本,在那里你可以像农场和矿山一样构建,我只是想知道,即使在我停止程序,然后重新开始之后,是否有可能恢复这些变量。假设我已经建立了4个农场,农场将是farm=4,我能把这个变量带回来吗?我知道如何创建一个页面,您可以在上面创建一个高分列表(这是我在猜谜游戏中做的),但我不知道在bash中是否可以做到这一点。您可以将所有需要的变量保存在一个文件中(使用here doc): 或 解释 放置here文档的位置取决于您的代码,如果您不必通过

好的,我想知道是否可以像bash中的变量一样保存。我正在写一个脚本,在那里你可以像农场和矿山一样构建,我只是想知道,即使在我停止程序,然后重新开始之后,是否有可能恢复这些变量。假设我已经建立了4个农场,农场将是farm=4,我能把这个变量带回来吗?我知道如何创建一个页面,您可以在上面创建一个高分列表(这是我在猜谜游戏中做的),但我不知道在bash中是否可以做到这一点。

您可以将所有需要的变量保存在一个文件中(使用here doc):

解释

  • 放置here文档的位置取决于您的代码,如果您不必通过示例将变量保存在循环中,则可以是最后一行
  • 放置
    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'%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
这将扩展到以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}
扩展(必须向下滚动一点才能到达)

(破)解 然后,您可以使用一个已损坏的解决方案将变量保存到文件中,如下所示:

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
}


请注意,像这样寻找外部文件会导致明显的安全问题,因此请确保您只小心使用此方法“${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
}