Bash -Удалить способ хранения переменной между прогонами?

Я создал bash script, который я запускаю каждый час с помощью crontab, и мне нужно сохранить одну переменную, чтобы я мог получить к ней доступ при следующем запуске. script изменяет переменную каждый раз, когда она запускается, поэтому я не могу ее жестко закодировать. Сейчас я пишу ее в txt файл, а затем читаю ее. Есть ли лучший способ сделать это, чем это? И способ, которым я читаю txt файл, - это то, что я нашел здесь, я его не понимаю, и это довольно неуклюже. Разве нет встроенной команды для этого? Во всяком случае, здесь применимый код, с некоторыми измененными переменными, чтобы упростить его чтение.

while read x; do
  var=$x
done < var.txt

# Do some stuff, change var to a new value

echo $var > var.txt

Переменная - это только одно целое число, поэтому текстовый файл чувствует себя излишним.

Ответ 1

Нет необходимости использовать var; x будет доступен для текущей оболочки. Альтернативно,

read var < var.txt
# do stuff with var
echo $var > var.txt

Я рекомендую использовать простой текстовый файл для хранения переменной. Однако существует (весьма сомнительная) опция самомодифицирующегося script. ТОЛЬКО ДЛЯ РАЗВЛЕКАТЕЛЬНЫХ ЦЕЛЕЙ!

#!/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

Ключ состоит в том, чтобы следующая строка была командой выхода, поэтому после ее выполнения ничего не происходит. Последняя строка - это переменная, которую вы хотите сохранить. Когда выполняется script, он read из своей последней строки. Прежде чем он выйдет, он использует sed для записи копии самого файла tema tema, причем последняя строка изменяется с текущим значением постоянного значения. Затем мы перезаписываем текущий script временным файлом (при условии, что у нас будет разрешение на это).

Но серьезно? Не делайте этого.

Ответ 2

Я знаю, что это старый вопрос. Но я все же решил разместить свое решение здесь в надежде, что это может быть полезно для других, которые приходят сюда в поисках способа сериализации env vars между сеансами.

Простым способом является просто написать "var_name = var_value" в файл, например "./environ". А затем "source./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" в функцию, то все исходные переменные будут видны внутри функции только потому, что "объявлять" по умолчанию объявляет переменные как локальные из них. Чтобы обойти это, вы можете либо "исправить" какую-либо функцию (или в своей "основной" функции), либо изменить. /environ, чтобы добавить "-g" после объявления (что делает соответствующую переменную глобальной). Например:

sed -i 's/^declare\( -g\)*/declare -g/' ./environ
# "\( -g\)?" ensure no duplication of "-g"

Ответ 3

1- Вы можете упростить свой script, так как у вас есть только одна переменная

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...

Ответ 4

В итоге я сделал следующее. Предпочитаете переменные в одном файле, но это немного раздувает код. Как это работает? Вы можете хранить несколько переменных в отдельном файле, скажем, переменные .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