Задача. Скопировать с удаленного ресурса самый старый файл. В исходной директории может лежать сегодняшний файл, может вчерашний, а может вообще не лежать...
Полезно в тех случаях, когда резервное копирование идет ночью, т.е. backup+копирование на резервный сервер может пройти до 00.00, а может не успеть и точную дату нашего backup файла мы не знаем.
bash скрипт. for, if, find...
#!/bin/bash
1. Монтируем удаленный ресурс
# размонтировать
umount /mnt/mnt_bckp/
# примонтировать
mount -o domain=Домен,username=Имя пользователя,password=Пароль //IP адрес/папка /mnt/mnt_bkp/
mount -o domain=Домен,username=Имя пользователя,password=Пароль //IP адрес/папка /mnt/mnt_bkp/
2. Определяем переменные
SOURCE_DIR=/mnt/mnt_bkp/backup/*.tgz #директория откуда копируем с маской
DEST_DIR=/mnt/backup/*.tgz # директория куда копируем с
# указанием маски
BACKUP_DIR="/mnt/backup/" # директория куда копируем
ARH_FILE=""
DEST_DIR=/mnt/backup/*.tgz # директория куда копируем с
# указанием маски
BACKUP_DIR="/mnt/backup/" # директория куда копируем
ARH_FILE=""
let im_copy=0 # признак того, что нашли нужный нам файл (если ресурс не один)
# или дополнительная проверка, что такой файл у нас уже лежит
3. Копируем. Для копирования используем команду find с опцией -mtime, нам нужны файлы созданные (измененные) за последние nn дней. Также для вывода можно использовать команду ls, которая вернет список файлов (использовать с опцией сортировки по дате создания).
Заводим еще одну глобальную переменную
dcopy=2 # копии за последние два дня
# опции команды find
# -mtime -5 - созданные или изменённые за последние 5 дней
# -atime -10 - время последнего обращения более 10 дней
# опции команды find
# -mtime -5 - созданные или изменённые за последние 5 дней
# -atime -10 - время последнего обращения более 10 дней
###### Работаем с резервом ########
# имена файлов тоже содержат дату (поэтому не заморачивалась с сортировкой)
for i in $(find $SOURCE_DIR -type f -mtime -$dcopy);
do
ARH_FILE=$i; #последний файл
done
echo "Последний архивный файл " $ARH_FILE
echo date
# копируем можно с доп.условием
if [[ ( "$ARH_FILE" != "" ) && ( $im_copy==0 ) ]] ; then
echo "Файл есть. Начинаю копирование c сервера... " $ARH_FILE
# копируем с шары
scp $ARH_FILE $BACKUP_DIR
let im_copy=1
else
echo "Нет новых файлов за последние " $dcopy " дня."
#exit
fi
echo $(date +%c)
# имена файлов тоже содержат дату (поэтому не заморачивалась с сортировкой)
for i in $(find $SOURCE_DIR -type f -mtime -$dcopy);
do
ARH_FILE=$i; #последний файл
done
echo "Последний архивный файл " $ARH_FILE
echo date
# копируем можно с доп.условием
if [[ ( "$ARH_FILE" != "" ) && ( $im_copy==0 ) ]] ; then
echo "Файл есть. Начинаю копирование c сервера... " $ARH_FILE
# копируем с шары
scp $ARH_FILE $BACKUP_DIR
let im_copy=1
else
echo "Нет новых файлов за последние " $dcopy " дня."
#exit
fi
echo $(date +%c)
Точно так же можно работать с удаленным сервером по ssh (если этот сервер вам доверяет)
SSH_HOST=XX.XX.XX.XX # IP адрес удаленного сервера
SSH_SOURCE_DIR=/mnt/backup/*.tgz
SSH_ARH_FILE=""
SSH_SOURCE_DIR=/mnt/backup/*.tgz
SSH_ARH_FILE=""
###### Работаем с сервером по SSH ########
# получить последний архив c рабочего сервера
for i in $(ssh $SSH_HOST "find $SSH_SOURCE_DIR -type f -mtime -$dcopy");
do
SSH_ARH_FILE=$i; #последний файл
done
echo "На сервере " $SSH_HOST " последний архивный файл " $SSH_ARH_FILE
if [ "$SSH_ARH_FILE" != "" ]; then
echo "Файл есть. Начинаю копирование c " $SSH_HOST " сервера... " $SSH_ARH_FILE
scp root@$SSH_HOST:$SSH_ARH_FILE $BACKUP_DIR #copy from server ssh
let im_copy=1
else
echo "Нет новых файлов за последние " $dcopy " дня"
#exit
fi
# получить последний архив c рабочего сервера
for i in $(ssh $SSH_HOST "find $SSH_SOURCE_DIR -type f -mtime -$dcopy");
do
SSH_ARH_FILE=$i; #последний файл
done
echo "На сервере " $SSH_HOST " последний архивный файл " $SSH_ARH_FILE
if [ "$SSH_ARH_FILE" != "" ]; then
echo "Файл есть. Начинаю копирование c " $SSH_HOST " сервера... " $SSH_ARH_FILE
scp root@$SSH_HOST:$SSH_ARH_FILE $BACKUP_DIR #copy from server ssh
let im_copy=1
else
echo "Нет новых файлов за последние " $dcopy " дня"
#exit
fi
4. Разархивировать полученный файл
tar -xzf $ARH_FILE
echo $(date +%c)
Немного мат.части.
find - поиск файла по заданным условиям
Некоторые ключи
-name
— искать по имени файла, при использовании подстановочных образцов параметр заключается в кавычки.-type
— тип искомого: f=файл, d=каталог, l=ссылка (link).-user, -group
— владелец: имя пользователя или UID, имя группы или GID
-atime
— время последнего обращения к файлу.-ctime
— время последнего изменения владельца или прав доступа к файлу.-mtime
— время последнего изменения файла.-newer другой_файл
— искать файлы созданные позже, чем другой_файл.-delete
— удалять найденные файлы.-exec command {} \;
— выполняет над найденным файлом указанную команду; обратите внимание на синтаксис.-ok
— перед выполнением команды указанной в -exec, выдаёт запрос.-depth
— начинать поиск с самых глубоких уровней вложенности, а не с корня каталога.-prune
— используется, когда вы хотите исключить из поиска определённые каталоги.Работа с функциями
function goaway {
exit
}
#вызовexit
}
goaway
Функция с параметрами
function param {
echo $1
}
#Вызываем и передаем один параметр Hello
Param Hello
Синтаксис цикла For
for i in $( ls ); do
echo item: $i
done
echo item: $i
done
Синтаксис цикла while:
COUNTER=0
while [ $COUNTER -lt 10 ]; do
echo The counter is $COUNTER
let COUNTER=COUNTER+1
done
Синтаксис if...then...else
if [ "foo" = "foo" ]; then
echo "это ИСТИНА"
else
echo "это ЛОЖЬ"
fi
echo "это ИСТИНА"
else
echo "это ЛОЖЬ"
fi
AND && -a
OR || -o
"опции
Сравнения
< -lt less then
> -gt greater then
<= -le less or equal
>= -ge greate or equal
== -eq equal
= равно
!= -ne not equal
Оператор -z проверяет, не пуста ли строка
if [ $ARH_FILE -z ]; then
echo "Пустая строка " $ARH_FILE
else
echo "Не пустая строка " $ARH_FILE
fi
Экран \ для символов <, >, (, )
Важно!!! Так как операторы < и > используются для перенаправления вывода, то в скрипте их надо экранировать
[ $im_copy \< 1 ]
Также экранировать следует круглые скобки, вместо () пишем \(\)
Использование [[
Сложные условия без экрана, с использованием двойных скобок [[, каждое условие отделяется круглыми скобками ()
[[ ( "$ARH_FILE" != "" ) && ( $im_copy==0 ) ]]
"опции
-a
и -o
соединяют выражения как логическое И и ИЛИ соответственно" Пример [ ! \( "a" = "$HOME" -o 3 -lt 4 \) ]
Сравнения
< -lt less then
> -gt greater then
<= -le less or equal
>= -ge greate or equal
== -eq equal
= равно
!= -ne not equal
Оператор -z проверяет, не пуста ли строка
if [ $ARH_FILE -z ]; then
echo "Пустая строка " $ARH_FILE
else
echo "Не пустая строка " $ARH_FILE
fi
Экран \ для символов <, >, (, )
Важно!!! Так как операторы < и > используются для перенаправления вывода, то в скрипте их надо экранировать
\<
или \>
.[ $im_copy \< 1 ]
Также экранировать следует круглые скобки, вместо () пишем \(\)
Использование [[
Сложные условия без экрана, с использованием двойных скобок [[, каждое условие отделяется круглыми скобками ()
[[ ( "$ARH_FILE" != "" ) && ( $im_copy==0 ) ]]
let
для вычисления выражений 1+1*2... используется функция let
let COUNTER=COUNTER+1
let res=(15+18)*100
Почитать
http://linuxland.itam.nsc.ru/howto/Bash-Prog-Intro.html -Из серии must-read
http://www.ibm.com/developerworks/ru/library/l-bash-test/ - от IBM
http://www.opennet.ru/docs/RUS/bash_scripting_guide/x6646.html - OpenNet
Просто линуксовый сайт
http://rus-linux.net - rus-linux.net
для вычисления выражений 1+1*2... используется функция let
let COUNTER=COUNTER+1
let res=(15+18)*100
Почитать
http://linuxland.itam.nsc.ru/howto/Bash-Prog-Intro.html -Из серии must-read
http://www.ibm.com/developerworks/ru/library/l-bash-test/ - от IBM
http://www.opennet.ru/docs/RUS/bash_scripting_guide/x6646.html - OpenNet
Просто линуксовый сайт
http://rus-linux.net - rus-linux.net