1

Я вот за пол часика накатал скрипт на bash и возникло пару вопросов. Я не спец и скорее всего он кривой.
1. Как в IF добавить второе значение.
Что бы он проверял условие: "Если первая и вторая папка существует то "

2. Как правильно вести лог всего что делается в скрипте. Подписывать как я к нужной строке вывод в нужный мне файл?

3. Как заставить tar писать свой вывод мне в файл? У него есть ключик -v. Вот это мне и надо записать. Это не проблема, но как к каждой его строчке вывода приписать дату?


#!/bin/bash

SOURCE_BACKUP_DIR="/home/xlin/samba/"
BACKUP_DIR="/home/xlin/backup/12345/"
COPY_DIR="/home/xlin/data/"
LOG_FILE="/var/log/backup_parus.log"

function backup_parus()
{
    echo "Compressing database..."
    tar -czf ${BACKUP_DIR}parus-`date "+%Y-%m-%d"`.tar.gz $SOURCE_BACKUP_DIR
    echo "Copy database Parus fo RAID disk...";
    cp ${BACKUP_DIR}parus* $COPY_DIR
    echo "`date` Backup Parus database in $COPY_DIR successfully" >> $LOG_FILE
}

if [ -d "$BACKUP_DIR" ]; then backup_parus
else
    echo "`date` Каталога ${BACKUP_DIR} не существует. Будет создан автоматически" >> $LOG_FILE
    mkdir -p $BACKUP_DIR
    backup_parus
    exit 1
fi

Прошу не пинать. Скрипты пишу редко )) Вот хочу разобраться.

MX 23.6 Libretto x86_64
Чем больше я работаю админом, тем больше понимаю, насколько волшебна фраза - "Нет технической возможности!"

2

xlin пишет:

1. Как в IF добавить второе значение.
Что бы он проверял условие: "Если первая и вторая папка существует то "

2. Как правильно вести лог всего что делается в скрипте. Подписывать как я к нужной строке вывод в нужный мне файл?

3. Как заставить tar писать свой вывод мне в файл? У него есть ключик -v. Вот это мне и надо записать. Это не проблема, но как к каждой его строчке вывода приписать дату?

1a) воспользоваться ключом -a

 Консоль:
[ -d dir1 -a -d dir2 ]

1b) воспользоваться связкой

[ -d dir1 ] && [ -d dir2 ]

1c) попросту повторить условие

if [ -d dir1 ]; then
 if [ -d dir2 ]; then
  # что-то делаем
 fi
fi

2) ага. можно ещё перенаправить вывод всего скрипта.
3) можно воспользоваться ключом -vv, и обрезать лишнее sed.


ЗЫЖ отличный скрипт bx

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

3

Спасибо. Закончил со скриптом. Буду его потом еще развивать. Наверное  ag

+ открыть спойлер
# Backup Parus database v 0.1
#!/bin/bash

SOURCE_BACKUP_DIR="/home/xlin/samba/"   # Указываем путь что будем бекапить
BACKUP_DIR="/home/xlin/backup/"         # Папка куда складывается бекап на сервере
COPY_DIR="/home/xlin/data/"             # Куда потом копировать с сервера готовый бекап (зеркалирование)
LOG_FILE="/var/log/backup_parus.log"    # Путь к файлу лога

function backup_parus()
{
    echo "Подождите. Выполняется процесс архивирования баз Паруса.";
    tar -czf ${BACKUP_DIR}parus-`date "+%Y-%m-%d"`.tar.gz $SOURCE_BACKUP_DIR
    echo "Копируется готовый архив на сервер с RAID массивом (зеркалирование).";
    cp ${BACKUP_DIR}parus* $COPY_DIR
    echo "`date` Backup Parus database in $COPY_DIR successfully" >> $LOG_FILE
}

if [ -d "$SOURCE_BACKUP_DIR" ]; then
 if [ -d "$COPY_DIR" ]; then
     echo "Путь к папке с базами PARUS найден...";
     echo "Указанный путь резервного копирования базы Parus найден";
 else
     echo "`date` WARNING: Проверте путь к директории, куда копируется файл бекапа PARUS" >> $LOG_FILE
     echo "`date` WARNING: Каталога ${COPY_DIR} не существует. Будет создан автоматически" >> $LOG_FILE
     mkdir -p $COPY_DIR
 fi
else
    echo "`date` ERROR: Проверте путь к директории, где хранятся базы PARUS" >> $LOG_FILE
    echo "ERROR: Произошла ошибка. Подробная информауия в /var/log/backup.log";
    exit 1
fi

if [ -d "$BACKUP_DIR" ]; then backup_parus
else
    echo "`date` Каталога ${BACKUP_DIR} не существует. Будет создан автоматически" >> $LOG_FILE
    mkdir -p $BACKUP_DIR
    backup_parus
    exit 1
fi
MX 23.6 Libretto x86_64
Чем больше я работаю админом, тем больше понимаю, насколько волшебна фраза - "Нет технической возможности!"

4 (20.02.2011 16:03:35 отредактировано XliN)

Почему не работает?

function test()
{
    if [ ! $(date +%w) = 6 -o  $(date +%w) = 0 ]; then
        echo "Сегодня не суббота и не воскресенье"
    else
        echo "Сегодня суббота или воскресенье"
    fi
}

А вот так работает )))

function test()
{
    if [ ! $(date +%w) = 6 ] && [ ! $(date +%w) = 0 ]; then
        echo "Сегодня не суббота и не воскресенье"
    else
        echo "Сегодня суббота или воскресенье"
    fi
}
MX 23.6 Libretto x86_64
Чем больше я работаю админом, тем больше понимаю, насколько волшебна фраза - "Нет технической возможности!"

5

А так?

...
if [ ! $(date +%w) = 6 -a  $(date +%w) = 0 ]; then
...
Был, был и весь вышел...

6

man test

-o ИЛИ

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

7 (20.02.2011 18:05:06 отредактировано XliN)

Оставил второй вариант. Работает и ладно. Скрипт сократил, а то что то много коментов было. Может чего криво там? Взгляните профессиональным глазом.

#!/bin/bash

SOURCE_BACKUP_DIR="/var/log/"                           # Указываем путь что будем бекапить
BACKUP_DIR_PARUS="/root/script/backup/"                 # Папка куда складывается бекап на сервере
SOURCE_DIR_SHABLON="/var/log/"                          # Папка к шаблонам Паруса
BACKUP_DIR_SHABLON="/root/script/backup/shablon/"       # Где будут лежать бекапы шаблонов
COPY_DIR="/root/script/backup_mirror/"                  # Куда потом копировать с сервера готовый бекап (зеркалирование)
LOG_FILE="/var/log/backup_test.log"                     # Путь к файлу лога

function backup_parus()
{
if [ ! $(date +%w) = 6 ] && [ ! $(date +%w) = 0 ]; then
       tar -czf ${BACKUP_DIR_PARUS}parus-`date "+%Y-%m-%d"`.tar.gz $SOURCE_BACKUP_DIR
       cp ${BACKUP_DIR_PARUS}parus* $COPY_DIR
       echo "`date` Backup Parus database in $COPY_DIR successfully" >> $LOG_FILE
else
   echo "`date` Backup базы Паруса не выполнен, т.к. сегодня $(date +%A)" >> $LOG_FILE
fi
}

function backup_shablon(){
if [ $(date +%d) = 01 ]; then
    tar -czf ${BACKUP_DIR_SHABLON}shablon-`date "+%Y-%m-%d"`.tar.gz $SOURCE_DIR_SHABLON
    cp ${BACKUP_DIR_SHABLON}shablon* $COPY_DIR
    echo "`date` Backup шаблонов выполнен, т.к. сенодня 1 чило нового месяца" >> $LOG_FILE
fi
}


if [ -d "$SOURCE_BACKUP_DIR" ] && [ -d "$COPY_DIR" ] && [ -d "$BACKUP_DIR_PARUS" ] && [ -d "$BACKUP_DIR_SHABLON" ]; then
        echo "`date` Пути к папкам найдены..." >> $LOG_FILE;
        backup_parus
        backup_shablon
        exit 1
        else
            echo "`date` Указанные пути к папкам не существуют, будут созданы автоматически" >> $LOG_FILE
            mkdir -p $COPY_DIR
            mkdir -p $BACKUP_DIR_PARUS
            mkdir -p $BACKUP_DIR_SHABLON
            backup_parus
            backup_shablon
            exit 1
fi

Мне не нравится последний кусок, где идет проверка на наличие папок и обращение к процедурам.

MX 23.6 Libretto x86_64
Чем больше я работаю админом, тем больше понимаю, насколько волшебна фраза - "Нет технической возможности!"

8

XliN пишет:

tar -czf ${BACKUP_DIR_PARUS}parus-`date "+%Y-%m-%d"`.tar.gz $SOURCE_BACKUP_DIR
cp ${BACKUP_DIR_PARUS}parus* $COPY_DIR

вот в этом месте может закончится свободное место. Необходимо отправить админу мыло, а лучше смску. А то получится так, что бекап не сделается. ac Проверьте содержимое $?, там должен быть ноль.

XliN пишет:

Мне не нравится последний кусок, где идет проверка на наличие папок и обращение к процедурам.

мне тоже. вот тут как раз надо использовать ИЛИ
вариант 1: использовать ключ -o
вариант 2: использовать связку ||.
ну и конечно сам бекап можно вынуть из if-fi.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

9

drBatty, Завтра попробую чуть переписать скрипт, что бы он как то по элегантней выглядел. Подправлю одну ошибку, которую я обнаружил вчера и если не чего получится отпишусь на форуме.

З.Ы. Кстати отличная идея проверять место на диске и сообщать об этом админу (то есть мне). Надо будет в будущем реализовать.  ag

MX 23.6 Libretto x86_64
Чем больше я работаю админом, тем больше понимаю, насколько волшебна фраза - "Нет технической возможности!"

10

drBatty пишет:

Проверьте содержимое $?, там должен быть ноль.

Проверил. Там нолик, а для чего это? Если ноль, то место на диске есть? Как это должно выглядеть?

Еще попутно вопросик. Как реализовать удаление определенного кол-ва файлов? Например удалять раз в месяц старые файлы бекапа. Ну штук 10 например.

Вот исправленный скрипт. Вроде работает. Протестил пару раз.
Что он делает скрипт:

  • Бекапит базу по будням

  • Бекапит шаблоны базы раз в месяц

Хочется еще замутить проверку места на дисках, где складываются архивы и слать мыло.

#!/bin/bash

SOURCE_BACKUP_DIR="/var/log/"                           # Указываем путь что будем бекапить
BACKUP_DIR_PARUS="/root/script/backup/"                 # Папка куда складывается бекап на сервере
SOURCE_DIR_SHABLON="/var/log/"                          # Папка к шаблонам Паруса
BACKUP_DIR_SHABLON="/root/script/backup/shablon/"       # Где будут лежать бекапы шаблонов
COPY_DIR="/root/script/backup_mirror/"                  # Куда потом копировать с сервера готовый бекап (зеркалирование)
LOG_FILE="/var/log/backup_test.log"                     # Путь к файлу лога
BACKUP_SHAB_DATE="25"

function backup_parus()
{
       tar -czf ${BACKUP_DIR_PARUS}parus-`date "+%Y-%m-%d"`.tar.gz $SOURCE_BACKUP_DIR
       cp ${BACKUP_DIR_PARUS}parus-`date "+%Y-%m-%d"`* $COPY_DIR
       echo $?
       echo "`date` Backup Parus database in $COPY_DIR successfully" >> $LOG_FILE
}

function backup_shablon()
{
    tar -czf ${BACKUP_DIR_SHABLON}shablon-`date "+%Y-%m-%d"`.tar.gz $SOURCE_DIR_SHABLON
    cp ${BACKUP_DIR_SHABLON}shablon-`date "+%Y-%m-%d"`* $COPY_DIR
    echo "`date` Backup шаблонов выполнен, т.к. сенодня $BACKUP_SHAB_DATE чило" >> $LOG_FILE
}

if [[ ! -d $BACKUP_DIR_SHABLON || ! -d $COPY_DIR ]]; then
    echo "`date` Папки не найдены!" >> $LOG_FILE
    mkdir -p $BACKUP_DIR_SHABLON
    mkdir -p $COPY_DIR
fi

if [[ ! $(date +%w) = 6 && ! $(date +%w) = 0 ]]; then
    backup_parus
    if [ $(date +%d) = $BACKUP_SHAB_DATE ]; then
        backup_shablon
    fi
else
    echo "`date` Backup базы Паруса не выполнен, т.к. сегодня $(date +%A)" >> $LOG_FILE
fi
MX 23.6 Libretto x86_64
Чем больше я работаю админом, тем больше понимаю, насколько волшебна фраза - "Нет технической возможности!"

11

XliN пишет:

Проверил. Там нолик, а для чего это? Если ноль, то место на диске есть? Как это должно выглядеть?

проверять надо после КАЖДОЙ команды, которая МОЖЕТ завершится с ошибкой.
если 0 - значит прошлая команда завершилась успешно. не ноль - ошибка. и надо что-то делать.

XliN пишет:

Как это должно выглядеть?

err=$?
if [ $err != 0 ]; then
  send_sms --to=admin --text="всё, [color=red][b][CENSORED][/b][/color]!!! при бекапе случилась СТРАШНАЯ НЕХ с кодом $err. Скрипт рухнул, бекапа нет! СРОЧНО приезжай!!!"
  exit $err
fi

как-то так.

XliN пишет:

Кстати отличная идея проверять место на диске и сообщать об этом админу (то есть мне). Надо будет в будущем реализовать.

идея довольно странная. Вы уверенны, что вы первый до такого додумались? Нет. Именно для этого и существует код ошибки.
есть и ещё вариант: читайте man bash на предмет опции -x. ну и man crontab на предмет отправки мыла. Идея такая: скрипт падает, а crond шлёт мыло.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

12 (09.03.2011 17:31:11 отредактировано Kettler)

Посмотрел на данный скрипт по идее подходит. Но мне надо чуток другое. Может кто поможет.
Есть папка например /video/ можно конечно забекапить всё но мне желательно заповать все файлы кроме последнего по дате

133018 2011-03-06 14:27 97-20110306142520.avi
1978918 2011-03-06 14:30 98-20110306142851.avi
2619746 2011-03-06 14:33 99-20110306143141.avi

Вот например упаковать всё кроме 2619746 2011-03-06 14:33 99-20110306143141.avi можно такое реализовать?

Ищу дополнительный заработок (удалёнка).
Пьянка без секса – признак алкоголизма.

13

Хотя как вариант пакую всю папку, но как удалить все кроме последней записи.

Ищу дополнительный заработок (удалёнка).
Пьянка без секса – признак алкоголизма.

14

Kettler пишет:

Есть папка например /video/ можно конечно забекапить всё но мне желательно заповать все файлы кроме последнего по дате

про ls -t наслышаны? ок. это сортировка по времени. вам не хватает удаления последней строки: sed '$d'

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

15

drBatty я в программировании не особ поэтому и прошу помощи если не трудно напишите полностью команду.
как удалить всё кроме последней записи.

Ищу дополнительный заработок (удалёнка).
Пьянка без секса – признак алкоголизма.

16

построение списка файлов

 Консоль:
$ /bin/ls -t | sed '1d;$d' | tee file_list

(обрезается первая строка, где "итого", и последняя, вам не нужная)
упаковка файлов из списка
 Консоль:
$ tar -cvvf arc.tar --files-from file_list

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

17

ЗЫЖ на самом деле можно и на лету паковать, только это очень долго, и куча проблем возникает в посте №16 самый лучший ИМХО способ.
кроме того, список можно обработать. например отсортировать по расширению, что-бы лучше сжалось. Именно так делает WinRAR.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

18

Спасибо! А как можно ещё удалить file_list ?

Ищу дополнительный заработок (удалёнка).
Пьянка без секса – признак алкоголизма.

19

Kettler пишет:

А как можно ещё удалить file_list ?

 Консоль:
$ rm file_list

внутри скрипта подтверждения не будет.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

20

Поидее конечно кастыль могу тормознуть демон запаковать после удалить и снова запустить.

Ищу дополнительный заработок (удалёнка).
Пьянка без секса – признак алкоголизма.

21

drBatty пишет:
Kettler пишет:

А как можно ещё удалить file_list ?

 Консоль:
$ rm file_list

внутри скрипта подтверждения не будет.

Пробывал он удаляет сам файл а мне надо файлы а точнее список который он в себе содержит

Ищу дополнительный заработок (удалёнка).
Пьянка без секса – признак алкоголизма.

22 (09.03.2011 19:08:42 отредактировано drBatty)

Kettler пишет:

Пробывал он удаляет сам файл а мне надо файлы а точнее список который он в себе содержит

э...

 Консоль:
$ while read file_name; do echo "$file_name"; done <file_list

вместо echo  можно вставить любую другую команду.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

23

Спс

Ищу дополнительный заработок (удалёнка).
Пьянка без секса – признак алкоголизма.

24

забыл сказать - спец-символы могут порушить скрипт.
можно сделать либо поиск по inode (составить список инодов можно так: $ ls -i | sed 's/ .*//'), а потом искать эти файлы по инодом командой

 Консоль:
$ find . -inum $INODE -exec file {} \;

а ещё можно заставить ls нормально выводить символы:
 Консоль:
$ ls --quoting-style=c

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

25 (10.03.2011 01:11:47 отредактировано Kettler)

Тут написал кое что но точно кривой))) гляньте что можно подправить)

#!/bin/bash

SOURCE_BACKUP_DIR="/share/video/"
BACKUP_DIR_VIDEO="/share/backup/video/"
LOG_FILE="/var/log/backup_video.log"
SIZE_MAX="10000"

rm $SOURCE_BACKUP_DIR*.jpg

size= du -shm $BACKUP_DIR_VIDEO
date=`date "+%Y-%m-%d"`

ls -t $SOURCE_BACKUP_DIR | sed '1d;$d' | tee file_list
ls -t $BACKUP_DIR_VIDEO | sed '1d;$d' | tee file_tar

while read file_name;
do echo $SOURCE_BACKUP_DIR"$file_name" >> file_name_dir;
done < file_list;

if [ $size>=$SIZE_MAX ]
 then
        while read file_name;
        do rm $BACKUP_DIR_VIDEO"$file_name";
        done < file_tar
        tar -cvvf $BACKUP_DIR_VIDEO"$date".tar -T file_name_dir
        echo "`$date` Архив создан..." >> $LOG_FILE;
 else
        tar -cvvf $BACKUP_DIR_VIDEO"$date".tar -T file_name_dir
        echo "`$date` Архив создан..." >> $LOG_FILE;
 fi
rm file_list file_name_dir file_tar
Ищу дополнительный заработок (удалёнка).
Пьянка без секса – признак алкоголизма.

26

rm $SOURCE_BACKUP_DIR*.jpg

картинки в сорсе убирать совсем нужно? или только что б в бекапе их не было?


size= du -shm $BACKUP_DIR_VIDEO

кавычки не нужны? сам триста лет не писал ничего, скрипт не тестировался?

27

Rabat эти 2 команды отрабатывают всё как надо)

Ищу дополнительный заработок (удалёнка).
Пьянка без секса – признак алкоголизма.

28

Kettler пишет:

rm $SOURCE_BACKUP_DIR*.jpg

вот тут кавычки не нужны. с кавычками звёздочка не раскроется. Однако, ИМХО, лучше писать всё-же так:

 Консоль:
find . -depth -name "$SOURCE_BACKUP_DIR*.jpg" -type f -exec rm -v {} \; -type d -exec rmdir {} \;

ключ depth нужен для того, что-бы find искала "наизнанку". Существует всего три способа обхода деревьев:
1) центрированный. это обход в алфавитном порядке. не используется, ибо медленно.
2) прямой - сначала посещаем корень, потом левое поддерево, потом правое, рекурсивно. Нам не подходит - когда мы посещаем корень - там что-то есть.
3) обратный - сначала обходим подкаталоги, а потом корень. именно это нам и надо - мы сначала удаляем файлы, а потом директории, в которых содержались эти файлы.

Подробнее про обход деревьев - Дональд Э. Кнут Искусство программирования. Том первый, ЕМНИП.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

29

Вот тут подскажите как обрезать
size= du -shm $BACKUP_DIR_VIDEO

А то правило тут не работает.
if [ $size>=$SIZE_MAX ]

Ищу дополнительный заработок (удалёнка).
Пьянка без секса – признак алкоголизма.

30

Kettler пишет:

А то правило тут не работает.
if [ $size>=$SIZE_MAX ]

1) в bash'е только один тип данных - СТРОКИ.
когда вы используете сравнение, вы сравниваете именно СТРОКИ данных. Но, если покурить man test (а именно test тут используется, хоть и называется квадратной скобкой[[[), то станет ясно, как сравнивать целые числа (в bash они 64х битные):

+ открыть спойлер

INTEGER1 -eq INTEGER2
              INTEGER1 is equal to INTEGER2

       INTEGER1 -ge INTEGER2
              INTEGER1 is greater than or equal to INTEGER2

       INTEGER1 -gt INTEGER2
              INTEGER1 is greater than INTEGER2

       INTEGER1 -le INTEGER2
              INTEGER1 is less than or equal to INTEGER2

       INTEGER1 -lt INTEGER2
              INTEGER1 is less than INTEGER2

       INTEGER1 -ne INTEGER2
              INTEGER1 is not equal to INTEGER2

Hint: используйте ПРОБЕЛЫ - гуру пишут, что это самый лучший комментарий! И ещё - старайтесь всё заключать в кавычки, если у вас нужно раскрыть переменные, используйте "двойные", иначе используйте 'одиночные'.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)