さて、bashで変数のように保存できるかどうか疑問に思いました。私はあなたが農場や鉱山のように構築するスクリプトを書いていますが、プログラムを停止してから再開した後でも、それらの変数を元に戻すことができるかどうか疑問に思っていました。したがって、4つのファームを構築したとしましょう。ファームはfarm = 4になりますが、この変数を何らかの方法で戻すことはできますか?ハイスコアリストを作成できるページの作成方法は知っていますが(推測ゲームで作成しました)、これがbashで可能かどうかはわかりません。
2 に答える
次の形式ですべてをファイルに書き込むことができます。
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
を持っていることです
シェル入力として再利用できる方法で引数を引用します
(私はこれをから入手しました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=%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
}
このような外部ファイルを入手すると、明らかなセキュリティの問題が発生することに注意してください。この方法のみを注意して使用してください。
必要なすべての変数をファイルに保存できます(here-docを使用)。
cat<<EOF>/path/to/file
var1="$var1"
var2="$var2"
EOF
以前の環境を再作成するには:
source /path/to/file
また
. /path/to/file
説明
- ヒアドキュメントを配置する場所はコードによって異なります。例によって変数をループに保存する必要がない場合は、最後の行にすることができます。
source
コマンドを配置する場所は、シェバンの後のスクリプトの先頭です。
ヘルプが言った:
$ LANG=C help source
source:sourcefilename[arguments]現在のシェルのファイルからコマンドを実行します。
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_file
- プレフィックスで:
printf '%q\n' $(set | grep "^prefix") > save_file
トリックをありがとうgniourf_gniourf printf
。