Forum Linux.pl

Programowanie => Bash, skrypty powłoki => Wątek zaczęty przez: mes mariusz w 2015-11-12, 10:34:01

Tytuł: Operacje na zmiennych przechowywanych w zewnętrznym pliku
Wiadomość wysłana przez: mes mariusz w 2015-11-12, 10:34:01
Witam.

Chcę (za pomocą skryptu sh) po detekcji ruchu (pakiet motion) wysłać maila z powiadomieniem. Nie mogę jednak pozwolić na wysyłanie maila z częstością większą niż, załóżmy  1 mail na 5 minut, gdyż w podobnej sytuacji usługodawca zablokuje mi możliwość wysyłki po SMTP.

Muszę więc zadbać o to by:

1). treść maila dopisana została do pliku np. /home/motion/mail.txt
2). jeśli od ostatniej wysyłki upłynęło więcej niż 5 minut to wyślij maila o zawartości /home/motion/mail.txt i wyczyść zawartość pliku /home/motion/mail.txt

Trzeba by gdzieś przechowywać informację o dacie ostatniej wysyłki.

W tym celu najlepiej chyba utworzyć zewnętrzny plik przechowujący wartości zmiennych. Niech to będzie /home/motion/variables.txt. Niech w tym pliku znajdują się różne zmienne (może się przydać w niedalekiej przyszłości). Niech plik ma zawartość:

var1 = x
var2 = y
last_sent = 2015-11-12_10:30


Teraz po każdej wysyłce maila należałoby wykonać akcję:

- otwórz plik /home/motion/variables.txt
- znajdź linię zaczynającą się na "last_sent = "
- usuń starą zawartość i wstaw tam bieżącą datę systemową


Natomiast przed wysyłką maila należałoby wykonać akcję:

- otwórz plik /home/motion/variables.txt
- znajdź linię zaczynającą się na "last_sent = "
- odczytaj wartość i porównaj z bieżącą datą systemową
- jeśli różnica między bieżącą data systemowa a datą pobraną ze zmiennej przekracza 5 minut wyślij maila.

Z góry dziękuję za pomoc w zakresie realizacji w bash:

- otwierania pliku,
- wyszukiwania linii zawierającej frazę np: "last_sent = "
- odczytu tego co stoi za taką frazą
- zapisu za taką frazą

Dzięki piękne.
Mariusz

Tytuł: Odp: Operacje na zmiennych przechowywanych w zewnętrznym pliku
Wiadomość wysłana przez: mes mariusz w 2015-11-12, 14:01:13
Gdyby chodziło o zamianę znanej frazy np.

"last_sent = 2015-11-12_10:30"

na

"last_sent = 2015-11-12_10:45"

można by po prostu użyć polecenia sed:

sed 's/last_sent = 2015-11-12_10:30/last_sent = 2015-11-12_10:45/' /home/motion/variables.txt

Problem w tym, że skrypt .sh nie będzie znał całej frazy "last_sent = 2015-11-12_10:30", chciałbym po prostu odnaleźć frazę "last_sent =", usunąć w tej linii wszystko, co za tą frazą i wstawić nową wartość.

Ktoś wie, jak to zrobić?
Tytuł: Odp: Operacje na zmiennych przechowywanych w zewnętrznym pliku
Wiadomość wysłana przez: ultr w 2015-11-12, 18:17:10
Cytuj
Ktoṡ wie, jak to zrobiċ?

Dokładnie tak samo, tylko używając wyrażenia regularnego:

sed 's/^last_sent *=.*$/last_sent = 2015-11-12_10:45/' /home/motion/variables.txt
Pamiętaj tylko przy wyrażeniu regularnym o ^ (i dla formalnoṡci $), aby łapaċ całą linię.
W przeciwnym wypadku sed dopasuje zmienne *kończące się* w podany sposób, a nie dokładnie o takiej nazwie.

Może przydać ci się też parametr -i polecenia sed: man sed
Tytuł: Odp: Operacje na zmiennych przechowywanych w zewnętrznym pliku
Wiadomość wysłana przez: ultr w 2015-11-12, 18:27:21
Cytuj
- otwierania pliku,

Linia po linii:

while read -r line; do
  echo $line
done < plik.txt

Cytuj
- wyszukiwania linii zawierającej frazę np: "last_sent = "

Jak wyżej, dodając w pętli warunek z wyrażeniem regularnym:

  REGEXP='^last_sent *= *(.*)$'
  if [[ "$line" =~ $REGEXP ]]; then
    ...
  fi

Cytuj
- odczytu tego co stoi za taką frazą

Powyższy warunek pozwoli odczytać wybrane fragmenty z tablicy BASH_REMATCH:

    echo "${BASH_REMATCH[1]}"

Cytuj
- zapisu za taką frazą

Jak w poprzednim poście, z użyciem sed.
Albo możesz na bieżąco w pętli wypluwać nową zawartość pliku linia po linii do bufora, zmieniając niektóre linie, a na koniec wypchnąć bufor do pliku:

echo "$bufor" > plik.txt