Pełny backup danych ze strony WWW dzięki CRON+Bash

Sytuacja z życia wzięta. Poszukiwałem jakiegoś dobrego sposobu, zautomatyzowanego najlepiej do systematycznego wykonywania kopii bezpieczeństwa  plików na serwerze, oraz bazy {{MySQL}}. Nic nie znalazłem, więc zacząłem nieco kombinować. W sieci jedyne pomocne rzeczy,  jakie znajdywałem to fakt, że:

  • najlepiej wykorzystać do tego {{Bash}}’a;
  • skoro ↑ to potrzeba też {{CRON}}’a.

Super – pomyślałem. Korzystam z Linuxpl.com, który stoi na serwerze {{Debian}}’owym, mam dostęp do {{CRON}}’a, więc wszystko da się zrobić. No ale, przecież nie znam {{Bash}}’a. Krótkie studiowanie samego języka, parę porad od (nie)znajomych i oto jest, mój pierwszy skrypt napisany w {{Bash}}’u, który zarazem niezmiernie może ułatwić mi życie.

Analiza kodu

  1. #!/bin/bash
  2. AKTUALNY=`date +%F`
  3. WYWAL=`date +%F -d"-XX day"`

Zmienna AKTUALNY wprowadza do skryptu po prostu obecną datę – wykonania skryptu. WYWAL odejmuje od daty wykonania skryptu XX dni.

  1. if [ -e /home/{user}/{katalog}/$WYWAL.7z ]
  2. then
  3. rm /home/{user}/{katalog}/$WYWAL.7z
  4. tar cpvfP /home/{user}/{katalog}/www.tar /home/{user}/
  5. /usr/local/mysql/bin/mysqldump {tabela_bazy} -u{użytkownik} -p{hasło} > /home/{user}/{katalog}/{tabela_bazy}.sql
  6. 7z a -mx9 /home/{user}/{katalog}/$AKTUALNY.7z /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql
  7. rm /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql

Jeśli istnieje AKTUALNY – XX dni wtedy, podejmij akcje:

  1. Usuń plik AKTUALNY – XX dni;
  2. Stwórz kopię zapasową katalogu /home/ użytkownika, pakując go bez kompresji, z zachowaniem praw dostępu do pliku www.tar;
  3. Pobierz odpowiednią tabelę bazy danych i zapisz ją;
  4. Spakuj z maksymalną kompresją plik www.tar oraz kopię tabeli bazy danych do pliku AKTUALNY.7z;
  5. Usuń pozostawione zbędne pliki, które są w archiwum *.7z.

Jeśli natomiast na serwerze nie ma pliku AKTUALNY-XX dni podejmij te same akcje, ale nie usuwaj czegoś, czego nie ma i tak na serwerze (linia nr 7 ↑).

  1. else
  2. tar cpvfP /home/{user}/{katalog}/www.tar /home/{user}/
  3. /usr/local/mysql/bin/mysqldump {tabela_bazy} -u{użytkownik} -p{hasło} > /home/{user}/{katalog}/{tabela_bazy}.sql
  4. 7z a -mx9 /home/{user}/{katalog}/$AKTUALNY.7z /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql
  5. rm /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql
  6. fi

W praktyce

Działanie skryptu jest bardzo proste. Pakuje wybrany przez nas folder do archiwum, następnie pobiera tabelę bazy {{MySQL}}, po czym pakuje obydwa pliki (archiwum i kopia bazy) i usuwa niepotrzebne pliki zostawiając jedno archiwum z kopią.

Ustawienia

W skrypcie (który załączę na końcu wpisu) napisałem, co należy zmienić i mniej więcej co należy posiadać. W razie pytań – komentujcie.

Dla przykładu, ja wykonuję skrypt raz na tydzień, więc nie mogę w polu XX day wpisać 30, ponieważ nie znajdzie mi takiego pliku z racji na fakt, że 7+7+7+7=28, a nie 30. Co daje więc efekt, że skrypt ma usunąć skrypt plik, który w nazwie ma aktualna_data-28dni – jest to jedyne rozwiązanie dla cotygodniowych backupów. Jeśli chcesz robić kopię codziennie, a po tygodniu usuwać stare kopie, to wpisujesz tam 7 – proste 8).

Najważniejsze jednak jest wykonanie prostego polecenia zmieniającego uprawnienia skryptu na wykonanie – bez tego ni rusz:

chmod +x skrypt.sh

Bądź z poziomu klienta {{FTP}} zmieniamy uprawnienia na 711.

Licencja

Skrypt udostępniam na licencji {{GPL}} v. 3. Co oznacza, że możecie z nim robić, co chcecie, ale zachowajcie dane autora ;). Byłbym niezmiernie wdzięczny za wszelakie sugestie rozwojowe, bo ktoś może mieć większy łeb ode mnie i podsunie jakieś pomysły.

Skrypt – pobieranie

Zaznacz wszystko i zapisz pod dowolną nazwą, z rozszerzeniem sh – a z poziomu {{CRON}}’a wpisujesz sh /home/{user}/{katalog}/backup.sh i ma działać. Pamiętaj o uzupełnieniu danych w skrypcie.

  1. #!/bin/bash
  2.  
  3. # Skrypt wykonujący kopię plików na serwerze oraz wybranej tabeli bazy MySQL na serwerach Uniksowych z dostępem do zadań CRON.
  4. # Autor: Filip (inzaghi89) Cierpich
  5. # URL: http://keepmind.eu
  6. # Mail: filip małpa keepmind dot eu
  7. # Licencja: GPL v. 3
  8.  
  9. # By skrypt działał poprawnie należy:
  10. # - Zamienić:
  11. # -- XX na ilość dni
  12. # -- {user} na naszą nazwę użytkownika w katalogu /home/ na danym serwerze
  13. # -- {katalog} na folder/katalog, w którym ma być zapisana kopia - katalog MUSI być stworzony ręcznie
  14. # -- {tabela_bazy} na tabelę, którą ma pobrać skrypt
  15. # -- {użytkownik} na nazwę użytkownika, za pośrednictwem której logujemy się do PHPmyAdmin
  16. # -- {hasło} na hasło, za pośrednictwem której logujemy się do PHPmyAdmin
  17. #
  18. # - Posiadać:
  19. # -- Uprawnienia wykonania skryptu na serwerze
  20. # -- Zainstalowaną paczkę p7z-full
  21. # -- Dostęp do zadań CRON na serwerze
  22.  
  23. # 2010-03-20 modyfikacja skryptu dzięki uwadze JaspEra: http://blog.keepmind.eu/pelny-backup-danych-ze-strony-www-dzieki-cronbash.html#comment-856
  24.  
  25. AKTUALNY=`date +%F` #odpowiada za nazwę pliku - aktualna data, np. 2010-03-18
  26. WYWAL=`date +%F -d"-XX day"` #odejmuje od aktualnej daty XX dni. Np. 2010-03-18 - 10 = 2010-03-08
  27.  
  28. if [ -e /home/{user}/{katalog}/$WYWAL.7z ]
  29. then
  30. rm /home/{user}/{katalog}/$WYWAL.7z #jeśli istnieje plik 2010-03-08.7z (czyli aktualna data - xx dni = usuń go)
  31. fi
  32. tar cpvfP /home/{user}/{katalog}/www.tar /home/{user}/ #pakuje katalog /home/{user}/ do pliku www.tar
  33. /usr/local/mysql/bin/mysqldump {tabela_bazy} -u{użytkownik} -p{hasło} > /home/{user}/{katalog}/{tabela_bazy}.sql #pobiera tabelę_bazy, którą zdefiniujemy do pliku tabela_bazy
  34. 7z a -mx9 /home/{user}/{katalog}/$AKTUALNY.7z /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql #pakuje z najwyższym stopniem kompresji do formatu 7z - wymagany pakiet p7z-full
  35. rm /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql #usuwa plik www.tar i tabela_bazy.sql, które krok wcześniej spakował
Ten wpis został opublikowany w kategorii Blog, Linux, Programowanie, Programy, Techniczne i oznaczony tagami , , , , , , , . Dodaj zakładkę do bezpośredniego odnośnika.

19 odpowiedzi na Pełny backup danych ze strony WWW dzięki CRON+Bash

  1. Piecia pisze:

    A projekt automysqlbackup http://sourceforge.net/projects/automysqlbackup/ nie byłby lepszy do backupu baz mysql?

  2. JaspEr pisze:

    A nie byłoby prościej, żeby w między if … fi umieścić kasowanie pliku (jeśli istnieje) a resztę wrzucić poza ten blok, bo i tak jest wykonywana (archiwizacja, mysqldump, kompresja)?

    if [ -e /home/{user}/{katalog}/$WYWAL.7z ]
      then
      rm /home/{user}/{katalog}/$WYWAL.7z #jeśli istnieje plik 2010-03-08.7z (czyli aktualna data - xx dni = usuń go)
    fi #jeśli nie ma
     
    tar cpvfP /home/{user}/{katalog}/www.tar /home/{user}/ #pakuje katalog /home/{user}/ do pliku www.tar
    /usr/local/mysql/bin/mysqldump {tabela_bazy} -u{użytkownik} -p{hasło} > /home/{user}/{katalog}/{tabela_bazy}.sql #pobiera tabelę_bazy, którą zdefiniujemy do pliku tabela_bazy
    7z a -mx9 /home/{user}/{katalog}/$AKTUALNY.7z /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql #pakuje z najwyższym stopniem kompresji do formatu 7z - wymagany pakiet p7z-full
    rm /home/{user}/{katalog}/www.tar /home/{user}/{katalog}/{tabela_bazy}.sql #usuwa plik www.tar i tabela_bazy.sql, które krok wcześniej spakował

    Łatwiej potem, jeśli zajdzie potrzeba zmian modyfikować tylko jeden zestaw poleceń. To nie jest kwestia znajomości/nieznajomości basha, tak po prostu zrobiłbym to w jakimkolwiek „języku”.

  3. Pingback: Backup danych na serwerze

  4. Uruchomienie cron'em a ręcznie pisze:

    Witam.
    Przy uruchomieniu za pomocą crona poniższego pliku ze skryptem jak wyżej:
    58 12 * * * root /root/cron_polecenia_skrypt/kompresja_kasowanie_thunderbird.sh

    skompresowany plik nie zawiera wszystkich plików.

    Po uruchomieniu ręcznie w pisując w terminalu polecenie:
    /./root/cron_polecenia_skrypt/kompresja_kasowanie_thunderbird.sh

    wszystkie dane są prawidłowo zapisane w piku tar i skompresowane za pocą 7z.

    Skrypt mam taki:

    #AKTUALNY5="mozilla-7z_`date +%F_%H.%M.%S`" #odpowiada za nazwę pliku - aktualna data, np. 2010-03-18
    WYWAL6_=thunderbird-7z_`date +%F_%H.%M.%S -d"-03 day"` 
     
     
    if [ -e /arch/Backup/$WYWAL6_.7z ]
    then
    rm /arch/Backup/$WYWAL6_.7z #jeśli istnieje plik 2010-03-08.7z (czyli aktualna data - xx dni = usuń go)
    fi
    tar cpvfP /arch/Backup/thunderbird.tar /home/dariusz/.thunderbird/ 
    #-u{użytkownik} -p{hasło} > /home/{user}/{katalog}/{tabela_bazy}.sql #pobiera #tabelę_bazy, którą zdefiniujemy do pliku 
    ##tabela_bazy
    7z a -mhe=on -pziyjctmmo1! -mx9 /arch/Backup/"thunderbird-7z_`date +%F_%H.%M.%S`".7z /arch/Backup/thunderbird.tar 
    #/home/{user}/{katalog}/{tabela_bazy}.sql pakuje z #najwyższym stopniem kompresji do formatu 7z - wymagany pakiet p7z-full
    rm /arch/Backup/thunderbird.tar 
    #/home/{user}/{katalog}/{tabela_bazy}.sql #usuwa plik www.tar i tabela_bazy.sql, które krok #wcześniej spakował
     
    echo "`date` thunderbird" >> /root/thunderbird.txt

    chmod -R 700 /arch
    chown -R root.root /arch/Backup

    Co z tym zrobić?
    Czy ktoś sie z tym już spotkał?

  5. inzaghi89 pisze:

    W ogóle nie rozumiem Twojego wpisu z cron, dlaczego masz jako wykonanie skryptu sh: root /ściezka/skrypt.sh, a nie po prostu „sudo sh…”, albo „sh”.

    Cron dla roota zedytujesz poprzez crontab -e root. Tam dodaj sobie ten skrypt jako zapis:
    sh /root/cron_polecenia_skrypt/kompresja_kasowanie_thunderbird.sh

    Sam skrypt wydaje się być ok. Poza tym sprawdź syslog, czy jakimiś errorami nie pluje.

  6. Uruchomienie cron'em a ręcznie pisze:

    Nic to nie daje, niestety.
    Szukam rozwiązania co z tym zrobić…

  7. neonek pisze:

    hej,

    a da się wykonać polecenie cron z pominięciem danego katalogu?

    pzrd

  8. Adam pisze:

    Jak tak stworzoną kopię przywrócić, tzn. zastąpić aktualne pliki wykonaną kopią.

    W skrócie jak z tych kopii zrobić backup?

    • inzaghi89 pisze:

      Rzekłbym – od tyłu :).
      7z x /home/{user}/{katalog}/$AKTUALNY.7z #Gdzie AKTUALNY do data backupu.
      I tutaj polecam np. MidnightCommander żeby wybrać sobie foldery/pliki, które chcesz wypakować i nadpisać z archiwum tar.
      By przywrócić bazę MySQL:
      /usr/local/mysql/bin/mysql {tabela_bazy} -u{użytkownik} -p{hasło} < /home/{user}/{katalog}/{tabela_bazy}.sql

  9. Przemek pisze:

    Proszę o pomoc,

    Jak dokładnie powinien wyglądać plik jeśli nie mam możliwości granie 7z i chciałbym pełny backup zapisywać jako tar ? Oraz dodać przykładowo dwie bazy danych do porabia.

    P.S. Świetny skrypt :)

    • inzaghi89 pisze:

      Jeśli nie masz możliwości instalacji 7z, to usuń po prostu linijkę z 7z (#33), która odpowiada za pakowanie/kompresję. Polecam jednak czymś sobie to skompresować. Rar, zip, cokolwiek.

      W linii 34 znajduje się komenda do zrzutu bazy danych do pliku. Musisz podać login i hasło do bazy danych oraz jej nazwę. Następnie wskazać gdzie plik ma się zapisać.

  10. Norfear pisze:

    Macie może pomysł jak zrobić do tego automatyczne kasowanie staszych plików niz 3 dni?
    I pytanie numer dwa czy można jakoś zamienić tego tara na gzipa?

    AKTUALNY2=”www_`date +%F_%H.%M`”
    WYWAL2=www_`date +%F_%H.%M -d”-03 day”`

    if [ -e /home/xxx/backup/$WYWAL2.tar ]
    then
    rm /home/xxx/backup/$WYWAL2.tar
    fi
    tar -zcvf /home/xxx/backup/”www_`date +%F_%H.%M`”.tar /home/xxx/public_html/

    • inzaghi89 pisze:

      Hej, co do pytań. Masz poprawiony skrypt uwzględniający usuwanie archiwów sprzed 3 dni ;). Dodatkowo atrybut „-z” kompresował archiwum gzipem. Dodałem rozszerzenie tylko.

      AKTUALNY2="www_`date +%F_%H.%M`"
      WYWAL2="www_`date +%F_%H.%M -d --date="3 days ago`"
       
      if [ -e /home/xxx/backup/$WYWAL2.tar ]
      then
      rm /home/xxx/backup/$WYWAL2.tar
      fi
      tar -zcvf /home/xxx/backup/"www_`date +%F_%H.%M`".tar.gz /home/xxx/public_html/
      • Norfear pisze:

        Dziękuje za poprawiony skrypt.

        1. Czy plik spakowany musi tak się kończyć *.tar.gz nie może być po prostu samo *.gz?

        2. Jednak kasowanie jak nie działało tak nie działa.
        Przykładowe poprzednie nazwy pliku w tym folderze gdzie może kasować i tworzyć pliki to:

        www_2018-03-23_09.42.tar
        www_2018-03-24_14.22.tar
        www_2018-03-25_00.00.tar
        www_2018-03-27_08.15.tar.gz (no i ten nowy poprawiony skrypt)

        • inzaghi89 pisze:

          Teraz jeszcze zerknąłem i źle wkleiłem też w poprzednim komentarzu. Nie dodałem .gz do pozostałych nazw plików. I nie, nie musi się nazywać .tar.gz żeby był skompresowany plik. Może być jak najbardziej samo .tar.

          Poza tym teraz dopiero zauważyłem, że skoro chcesz usuwać poprzednie dni, robisz kopię codziennie, to bez sensu żeby sprawdzało godziny kopii. Ten skrypt będzie usuwał kopie, które powstały dokładnie 3 dni temu.

          AKTUALNY="www_`date +%F`"
          WYWAL="www_`date +%F --date="3 days ago"`"
           
          if [ -e /home/xxx/backup/$WYWAL.tar ]
          then
          rm /home/xxx/backup/$WYWAL.tar
          fi
          tar -zcvf /home/xxx/backup/$AKTUALNY.tar /home/xxx/public_html/

          Możesz również zrobić to w ten sposób:

          AKTUALNY="www_`date +%F`"
          
          find /home/xxx/backup/www\_* -mtime +3 -exec rm {} \;
          tar -zcvf /home/xxx/backup/$AKTUALNY.tar /home/xxx/public_html/

          Wówczas skrypt usunie wszystkie pliki starsze niż 3 dni.

          • Norfear pisze:

            No no no przyznaje. Ze ten skrypt drugi spełnił moje wymogi w 100% :) Bardzo dziękuje za gotowca

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *