bash—;在运行之间存储变量的更好方法?
我已经制作了一个bash脚本,我使用crontab每小时运行一次,我需要存储一个变量,以便下次运行时可以访问它。脚本每次运行时都会更改变量,因此无法硬编码。现在,我正在将它写入一个txt文件,然后将其读回。还有比这更好的方法吗?我读txt文件的方式是我在这里发现的,我不理解,而且有点笨重。是否没有用于此的内置命令?无论如何,下面是适用的代码,其中一些变量已更改,以便于阅读bash—;在运行之间存储变量的更好方法?,bash,variables,text,storage,Bash,Variables,Text,Storage,我已经制作了一个bash脚本,我使用crontab每小时运行一次,我需要存储一个变量,以便下次运行时可以访问它。脚本每次运行时都会更改变量,因此无法硬编码。现在,我正在将它写入一个txt文件,然后将其读回。还有比这更好的方法吗?我读txt文件的方式是我在这里发现的,我不理解,而且有点笨重。是否没有用于此的内置命令?无论如何,下面是适用的代码,其中一些变量已更改,以便于阅读 while read x; do var=$x done < var.txt # Do some stuff,
while read x; do
var=$x
done < var.txt
# Do some stuff, change var to a new value
echo $var > var.txt
读取x时;做
var=$x
donevar.txt
该变量只是一个整数,因此文本文件感觉有些多余。无需使用
var
<代码>x将在当前外壳的范围内。或者
read var < var.txt
# do stuff with var
echo $var > var.txt
读取varvar.txt
我建议使用一个简单的文本文件来存储变量。但是,有一个自修改脚本的选项(非常值得怀疑)仅用于娱乐目的强>
#!/bin/bash
read val < <( tail -n 1 "$0" )
(( val++ ))
echo "$val"
tmp=$(mktemp /tmp/XXXXXXX)
sed '$s/.*/'$val'/' "$0" > "$tmp"
mv "$tmp" "$0"
exit
0
#/bin/bash
读取val<“$tmp”
mv“$tmp”$0
出口
0
关键是要让下一行到最后一行是exit命令,这样之后就不会执行任何命令。最后一行是要持久化的变量值。当脚本运行时,它从自己的最后一行读取。在退出之前,它使用sed
将自身的副本写入临时文件,最后一行用持久值的当前值修改。然后我们用临时文件覆盖当前脚本(假设我们有这样做的权限)
但说真的?不要这样做。1-您可以简化脚本,因为您只有一个变量
var=`cat var.txt`
# Do some stuff, change var to a new value
echo $var > var.txt
2-您可以在环境中存储变量:
export var
# Do some stuff, change var to a new value
但是您需要提示它
。script.ksh
(圆点位于底部)。但是它不应该有“退出”,我不确定这在cron中是否有效…我最后做了以下工作。希望将变量放在一个文件中,但这会使代码稍微膨胀。这个阅读工具是怎么工作的?您可以将多个变量存储在一个单独的文件中,比如variables.txt,然后将主程序保存在main.sh中。不过,最好编写单独的脚本来加载和保存变量
对于varibles.txt:
A=0
B=0
C=0
对于main.sh:
#!/bin/bash
#reload variables
A=`cat ./variables.txt|grep "A="|cut -d"=" -f2`
B=`cat ./variables.txt|grep "B="|cut -d"=" -f2`
C=`cat ./variables.txt|grep "C="|cut -d"=" -f2`
#print variables
printf "$A\n"
printf "$B\n"
printf "$C\n"
#update variables
A=$((($A+1)))
B=$((($B+2)))
C=$((($C+3)))
#save variables to file
#for A
#remove entry for A
cat ./variables.txt|grep -v "A=">>./tmp.txt
#save entry for A
printf "A=$A\n">>./tmp.txt
#move tmp.txt to variables.txt
mv ./tmp.txt ./variables.txt
#for B
#remove entry for B
cat ./variables.txt|grep -v "B=">>./tmp.txt
#save entry for B
printf "B=$B\n">>./tmp.txt
#move tmp.txt to variables.txt
mv ./tmp.txt ./variables.txt
#for C
#remove entry for C
cat ./variables.txt|grep -v "C=">>./tmp.txt
#save entry for C
printf "C=$C\n">>./tmp.txt
#move tmp.txt to variables.txt
mv ./tmp.txt ./variables.txt
我知道这是个老问题。但是,我仍然决定在这里发布我的解决方案,希望它可能对来这里寻找在会话之间序列化环境变量的方法的其他人有所帮助 简单的方法就是将“var\u name=var\u value”写入一个文件,比如“/environ”。然后在接下来的会话中选择“source./environ”。例如:
echo "var1=$var1" > ./environ
保存变量所有属性的一种更全面(更优雅)的方法是使用“declare-p”:
稍后,在“source./environ”之后,您可以获得var1 var2,其中除其值外还恢复了所有属性。这意味着它可以处理数组、整数等
不过,“declare-pxx”有一个警告:如果将“source./environ”包装到一个函数中,那么所有源变量在函数中都是可见的,因为默认情况下“declare”将变量声明为本地变量。为了避免这种情况,您可以从任何函数中(或在“main”函数中)选择“source”,或者修改./environ以在declare之后添加“-g”(这使相应的变量成为全局变量)。例如:
sed -i 's/^declare\( -g\)*/declare -g/' ./environ
# "\( -g\)?" ensure no duplication of "-g"
要在两次运行之间存储多个变量,我考虑的解决方案是将它们以
my_var=my_value
格式保存在一个单独的文件中
然后,我包括两个函数来设置和检索变量
# Here I store the variables and their values
my_var_x=1
my_var_y=boo
my_var_z=0
context=./context.dat
function update_variables(){
# update the variable context
source $context
}
function set_variable(){
# store variable
variable=$1 #variable to be set
value=$2 # value to give to the value
# modify the file storing the value
sed -i 's/'${variable}'.*/'${variable}'='${value}'/' $context
}
##################
# Test code
echo var_x
update_variables
echo var_x
# do something
set_variable var_x 2
echo $var_x
这是其中之一。使用这种方法,您需要先创建存储文件,然后为每个变量创建每一行。此外,context.dat是任何其他脚本都可以预先访问的。刚刚发现了这个伟大的简单项目(重写的fork)。一个简单但功能强大的bash键/值对存储。看起来很完美。在幕后,每个数据库都是一个目录,每个键都是一个文件,值都在文件中
- 微型键值数据库
- 可配置数据库目录(默认值:
)~/.kv sh
- 通过
$导入函数时使用/kv sh
- 完全数据库转储/恢复
- 支持辅助只读默认数据库
取决于您的用例,这可能是多余的,但是如果您需要存储和跟踪多个变量(或来自多个脚本),那么考虑使用具有命令行接口()的命令,通常在Linux /MACOS系统上预安装OOTB。
DB='storage.DB'
关键字1='欧元兑美元'
VAL1=1.19011
关键字2='英镑欧元'
VAL2=1.16829
#如果不存在,则创建表(只需运行一次)
QUERY_CREATE=“如果不存在记录,则创建表(id整数主键,名称文本不为NULL,值数字不为NULL);”
sqlite3“$DB”“$QUERY\u CREATE”
#将键值对写入数据库(每次创建新行)
QUERY_INSERT=“插入记录(名称、值)值('${KEY1}','${VAL1}');”
sqlite3“$DB”“$QUERY\u INSERT”
#将键值对写入数据库(替换以前的值!)
#使用42作为硬编码行ID
QUERY_REPLACE=“替换为记录(id、名称、值)值(42,${KEY2}',${VAL2}”)
sqlite3“$DB”“$QUERY\u REPLACE”
#从数据库中读取值
QUERY_SELECT1=“从记录中选择值,其中name='${KEY1}'
QUERY_SELECT2=“从记录中选择值,其中name='${KEY2}'
回显“*****$KEY1*****”
#将db值存储在变量中
db_value1=$(sqlite3“$db”“$QUERY\u SELECT1”)
echo$db_值1
##产出:1.19011
回声
context=./context.dat
function update_variables(){
# update the variable context
source $context
}
function set_variable(){
# store variable
variable=$1 #variable to be set
value=$2 # value to give to the value
# modify the file storing the value
sed -i 's/'${variable}'.*/'${variable}'='${value}'/' $context
}
##################
# Test code
echo var_x
update_variables
echo var_x
# do something
set_variable var_x 2
echo $var_x
. ./kv-sh # import kv-sh functions (use default database directory; see
configuration environment variables for available options)
kvset <key> <value> # assign value to key
kvget <key> # get value of key
kvdel <key> # delete key
kvexists <key> # check if key exists
kvkeys {-l|-d|-a} # list all keys (-l local only, -d default only, -a all (default))
kvlist {-a} # list all key/value pairs (-a all keys, including default)
kvdump {-a} # database dump (-a all keys, including default)
kvimport # database import (overwrite)
kvrestore # database restore (clear and restore)
kvclear # clear database
DB_DIR="/tmp/.kv" DB_DEFAULTS_DIR="/tmp/.kv-default" . ./kv-sh