2012-09-08 8 views
10

Zrobiłem skrypt bash, który uruchamiam co godzinę z crontab, i muszę przechowywać jedną zmienną, aby móc uzyskać do niej dostęp przy następnym uruchomieniu. Skrypt zmienia zmienną za każdym razem, gdy jest uruchamiany, więc nie mogę go zakodować. Teraz piszę to do pliku txt, a następnie odczytuję go. Czy jest lepszy sposób na zrobienie tego niż to? A sposób, w jaki czytam plik txt jest czymś, co znalazłem tutaj, nie rozumiem tego i jest trochę przylegający. Czy nie ma wbudowanego w to polecenia? W każdym razie, tutaj jest odpowiedni kod, z niektórymi zmiennymi zmienionymi, aby ułatwić czytanie.bash - lepszy sposób na przechowywanie zmiennej między przebiegami?

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

# Do some stuff, change var to a new value 

echo $var > var.txt 

Zmienna to tylko jedna liczba całkowita, więc plik tekstowy wydaje się przesadzony.

+1

Krótki plik tekstowy przechowujący trwałe dane jest dokładnie taki, jak to zrobić, nic w tym nie mówi. – user4815162342

Odpowiedz

6

Nie trzeba używać var; x będzie w zasięgu aktualnej powłoki. Alternatywnie,

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

Polecam za pomocą prostego pliku tekstowego, aby zapisać zmienną. Istnieje jednak (wysoce wątpliwa) opcja samodostosowania skryptu. WYŁĄCZNIE DO CELÓW ROZRYWKI!

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

Kluczem do sukcesu jest mieć obok-to-ostatnia linia będzie polecenie exit, więc nic po nim wykonać. Ostatnia linia to wartość zmiennej, którą chcesz utrwalić. Po uruchomieniu skryptu jest on z jego ostatniej linii. Przed wyjściem używa sed, aby napisać kopię pliku temp, z ostatnią linią zmodyfikowaną bieżącą wartością trwałej wartości. Następnie nadpisujemy bieżący skrypt plikiem tymczasowym (zakładając, że będziemy mieli na to zgodę).

Ale poważnie? Nie rób tego.

+0

Dzięki, to o wiele prostsze. Czy pliki tekstowe są najlepszym sposobem na zrobienie tego? – shardbearer

+0

@shardbearer: To zależy. Możesz wybierać spośród plików, baz danych, innych bardziej egzotycznych magazynów utrzymywania obiektu Java/Ruby/Pythona lub utrzymywać program w nieskończonej pętli (z osadzonymi odpowiednimi czasami snu) i przechowywać wartość w pamięci, w zależności od Twoich ogólnych wymagań są. Trwałość plików jest zwykle wystarczająco dobra. Jeśli wchodzisz w system mongo z tysiącami plików i katalogów (tak jak to ostatnio zostało napisane w witrynie S.O.), musisz poświęcić trochę czasu na znalezienie odpowiedniej technologii. Powodzenia wszystkim. – shellter

+0

Downvoter: proszę skomentuj swój powód. Czy to z powodu obrzydliwego kodu modyfikującego? :) – chepner

1

1- Można uprościć skrypt, jak masz tylko jedna zmienna

var=`cat var.txt` 
# Do some stuff, change var to a new value 
echo $var > var.txt 

2- można zapisać zmienną w środowisku:

export var 

# Do some stuff, change var to a new value 

Ale trzeba monitować to . script.ksh (kropka na początku). Ale nie powinno to mieć "wyjścia" i nie jestem pewien, czy to zadziała w cron ...

-1

Skończyło się na tym, co następuje. Wolałby zmienne w jednym pliku, ale to powoduje nieznaczne rozrost kodu. Jak działa ta lektura? Możesz przechowywać wiele zmiennych w osobnym pliku, na przykład variables.txt, a następnie mieć swój główny program w powiedzeniu main.sh. Być może lepiej byłoby napisać osobne skrypty do ładowania i zapisywania zmiennych.

Dla varibles.txt:

A=0 
B=0 
C=0 

Dla 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 
+2

Bez obrazy, ale to jest straszne. Lepiej 'zródło' pliku' variables.txt' zamiast sam go parsować. Poza tym dostrzeżono bezużyteczne zastosowania kota! –

2

wiem, jest to stara sprawa. Ale nadal decyduję się na opublikowanie mojego rozwiązania w nadziei, że może to być pomocne dla innych, którzy przybywają tutaj, szukając sposobu serializacji varów między sesjami.

Prostym sposobem jest po prostu wpisanie "var_name = var_value" do pliku, powiedz "./environ". A następnie "source ./envrion" w kolejnych sesjach.Na przykład:

echo "var1=$var1" > ./environ 

Bardziej kompleksowe (? I elegancki) sposób, który utrzymuje wszystkie atrybuty zmiennych jest do korzystania z „Oświadczam -p”:

declare -p var1 var2 > ./environ 
# NOTE: no '$' before var1, var2 

Później, po „źródło./envrion "możesz otrzymać var1 var2 z przywróconymi wszystkimi atrybutami oprócz jego wartości. Oznacza to, że może on obsługiwać tablice, liczby całkowite itp.

Jedna uwaga dla "declare -p xx", chociaż: jeśli zawiniesz "source ./environ" do funkcji, to wszystkie źródła będą widoczne w funkcji tylko dlatego, że "deklaruj" domyślnie deklaruje zmienne jako lokalne. Aby to obejść, możesz albo "źródło" z dowolnej funkcji (albo w swojej "głównej" funkcji) lub zmodyfikować ./environ, aby dodać "-g" po zadeklarowaniu (co powoduje, że odpowiednia zmienna jest globalna). Na przykład:

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

To jest proste podejście i sam go używam. To wymaga opieki, jeśli niezaufani użytkownicy mogą zapisywać do pliku (np. Jeśli jest to plik '/ tmp', a nie początkowo utworzony), ponieważ zawiera on pełne możliwości powłoki pozyskiwania. Dbać! –

+0

@ TobySpeight masz rację, i dziękuję. –

Powiązane problemy