bash-лучший способ хранения переменной между прогонами?
Я сделал скрипт bash, который я запускаю каждый час с crontab, и мне нужно сохранить одну переменную, чтобы я мог получить к ней доступ при следующем запуске. Скрипт меняет переменную каждый раз, когда она запускается, поэтому я не могу ее жестко закодировать. Прямо сейчас я пишу его в txt-файл, а затем читаю его обратно. Есть ли лучший способ сделать это, чем это? И то, как я читаю txt-файл, это то, что я нашел здесь, я этого не понимаю, и это немного неуклюже. Разве для этого нет встроенной команды? Во всяком случае, вот применимый код, с некоторыми переменными, измененными, чтобы облегчить чтение.
while read x; do
var=$x
done < var.txt
# Do some stuff, change var to a new value
echo $var > var.txt
переменная является только одним целым числом, поэтому текстовый файл чувствует себя излишним.
5 ответов
нет необходимости использовать var
; x
будет в области текущей оболочки. Поочередно,
read var < var.txt
# do stuff with var
echo $var > var.txt
Я рекомендую использовать простой текстовый файл для хранения переменной. Однако существует (весьма сомнительный) вариант самоизменяющегося скрипта. ТОЛЬКО ДЛЯ РАЗВЛЕКАТЕЛЬНЫХ ЦЕЛЕЙ!
#!/bin/bash
read val < <( tail -n 1 "" )
(( val++ ))
echo "$val"
tmp=$(mktemp /tmp/XXXXXXX)
sed '$s/.*/'$val'/' "" > "$tmp"
mv "$tmp" ""
exit
0
ключ должен иметь предпоследнюю строку быть командой выхода, поэтому ничего после этого не будет выполняться. Последняя строка-это значение переменной, которое вы хочу упорствовать. Когда скрипт запускается, он read
s из собственной последней строки. Перед выходом он использует sed
для записи копии самого файла Toa temp, с последней строкой, измененной текущим значением постоянного значения. Затем мы перезаписываем текущий скрипт временным файлом (предполагая, что у нас будет разрешение на это).
а если серьезно? Не делай этого.
Я знаю, это старый вопрос. Но я все же решаю опубликовать свое решение здесь в надежде, что это может быть полезно для других, кто приходит сюда в поисках способа сериализации env vars между сессиями.
простой способ - просто записать " var_name=var_value "в файл, скажем"./окружающая среда." А потом: "источник ./ envrion " на следующих сессиях. Например:
echo "var1=$var1" > ./environ
более полный (и элегантным?) способ сохранения всех атрибутов переменных - использовать "declare-p":
declare -p var1 var2 > ./environ
# NOTE: no '$' before var1, var2
позже, после " source ./envrion " вы можете получить var1 var2 со всеми атрибутами, восстановленными в дополнение к его значению. Это означает, что он может обрабатывать массивы, целые числа и т. д.
одно предостережение для "declare-P xx", хотя: если вы обернете " источник ./environ "в функцию, тогда все исходные переменные видны внутри функции только потому, что" declare " по умолчанию объявляет переменные локальными. Чтобы обойти это, вы можете либо "источник" из любого функция (или в вашей" главной " функции )или измените./ environ добавить "- g " после объявления (что делает соответствующую переменную глобальной). Например:
sed -i 's/^declare\( -g\)*/declare -g/' ./environ
# "\( -g\)?" ensure no duplication of "-g"
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...
чтобы сохранить несколько переменных между запусками, решение, которое я рассмотрел, - сохранить их в формате my_var=my_value
в отдельном файле.
затем, я включаю две функции для установки и извлечения переменных
- в файле хранятся переменные и их значения:
назовем этот файл контексте.dat
# Here I store the variables and their values
my_var_x=1
my_var_y=boo
my_var_z=0
- в самом скрипте:
назовем файла multiple_run.sh
context=./context.dat
function update_variables(){
# update the variable context
source $context
}
function set_variable(){
# store variable
variable= #variable to be set
value= # 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
Это один из подходов, среди других. С помощью такого метода вам нужно создать файл хранения до и создать каждую строку для каждой переменной. Кроме того, контекст.dat априори доступен любому другому скрипту.
в итоге я сделал следующее. Предпочел бы переменные в одном файле, но это немного раздувает код. Как это работает? Вы можете хранить несколько переменных в отдельном файле, например переменные.txt, а затем ваша основная программа в say 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