Продолжаю автоматизировать работу сервера. В этот раз руки коснулись автоматизации создания архива с конфигурационными файлами. При этом задачи были поставлены следующие:
1. Пути для архивации должны лежать в отдельном файле.
2. Архивироваться должен на сетевой ресурс расшаренный под Windows Server. При этом во время архивирования он должен подключаться, а по окончании отключаться.
3. Архивы должны создавать раз в день/неделю/месяц (тут я добавил от себя, архивы будут хранится с одной ротацией)
Для написания был выбран perl и в итоге получился вот такой скрипт:
#!/usr/bin/perl
#########################################################################################
# Created: Zakharchenko Andrey Ruslanovich
# Date: 2010.01.20
# Description: Скрипт скрипт создания архива конфигурационных файлов
#########################################################################################
#--- основные переменные
$dst = '/var/files/backup_nt/GW-01';
$dst_local = '/var/files/backup/config';
$mount_path = '/var/files/backup_nt';
chop($hostname = `hostname`);
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time);
$year += 1900;
$mon += 1;
#--- преобразовываем формат даты с 1 на 01
sub setformatnumber {
if ($_[0] < 10 ) { return '0'.$_[0] }
else { return $_[0] }
}
#--- проверка подмонтирования директории для архивов
if (!`df -Hac | grep backup_nt`) {
system("mount $mount_path")
}
#--- проверяем на всякий случай доступность пути
if ( -d $dst ) {
#--- создаем список что архивировать
open(list,"/root/list/backup_list");
while($in=<list>) {
$in=~s/\s$//;
$what_backup=$what_backup." ".$in;
}
#--- создаем дневной архив
$to_backup = "$dst/day/$year-".setformatnumber($mon)."-".setformatnumber($mday).".day.$hostname.backup.config.tar.bz2";
system("/usr/bin/tar jvcf $to_backup $what_backup");
#--- удаляем старые дневные архивы
$rm_backup = "$dst/day/$year-".setformatnumber($mon)."-".setformatnumber($mday-2).".day.$hostname.backup.config.tar.bz2";
if ( -e $rm_backup) {
system ("/bin/rm -f $rm_backup");
}
#--- создаем бак за месяц
if ($mday eq 1 ) {
$to_backup = "$dst/month/$year-".setformatnumber($mon)."-".setformatnumber($mday).".month.$hostname.backup.config.tar.bz2";
system("/usr/bin/tar jvcf $to_backup $what_backup");
#--- удаляем старые месячные архивы
$rm_backup = "$dst/month/$year-".setformatnumber($mon-2)."-".setformatnumber($mday).".day.$hostname.backup.config.tar.bz2";
if ( -e $rm_backup ) {
system ("/bin/rm -f $rm_backup");
}
}
#--- создаем недельный архив
if ((localtime(time))[6] eq 1 ) {
$to_backup = "$dst/week/$year-".setformatnumber($mon)."-".setformatnumber($mday).".week.$hostname.backup.config.tar.bz2";
system("/usr/bin/tar jvcf $to_backup $what_backup");
#--- удаляем старые недельные архивы
$rm_backup = "$dst/week/$year-".setformatnumber($mon)."-".setformatnumber($mday-14).".week.$hostname.backup.config.tar.bz2";
if ( -e $rm_backup ) {
system ("/bin/rm -f $rm_backup");
}
}
}
#--- после завершения бекапа отмонтируем директорию
if (`df -Hac | grep backup_nt`) {
system("umount $mount_path")
}
Файл /root/list/backup_list выглядит следующим образом:
[root@gw-01 bin]# cat /root/list/backup_list
/boot
/etc
/root
/usr/local/etc
/var/named
/var/cron/tabs/root
[root@gw-01 bin]#
Заказчик заказал чтоб логи каждый день создавалась по следующими свойству, каждые 24 часов за прошлый день и ложись в пути ${dst}/2010/01/14 и в каждого первого числа создавалась за месяц по адресу ${dst}/2010/01/month. Было принято решение написать не большой sh скрипт и поместить его в cron
#!/bin/sh
#########################################################################################
# Created: Zakharchenko Andrey Ruslanovich
# Date: 2010.01.16
# Description: Скрипт генерации статистики squid по средствам sarg
#########################################################################################
#--- основные переменные
dst='/usr/local/www/data/stat'
sarg='/usr/local/bin/sarg'
create_dir='/bin/mkdir -p'
ddate='/bin/date'
check=0
#--- переменные для дат
current_month_number=`${ddate} "+%m"`
last_month_number=${current_month_number}
current_year_number=`${ddate} "+%y"`
last_year_number=${current_year_number}
current_day_number=`${ddate} "+%d"`
last_day_number=${current_day_number}
#--- составляем основотую команду
command="${ddate} -v${current_day_number}d -v${last_month_number}m -v${last_year_number}y -v-1d "
#--- если сегодня 2010.01.01
if ([ `${ddate} +%m` -eq 1 ] && [ `${ddate} +%d` -eq 1 ])
then
${create_dir} ${dst}/`$command +%Y`/`$command +%m`/"month"
${sarg} -d 01/`$command +%m`/`$command +%Y`-`$command +%d`/`$command +%m`/`$command +%Y` -o ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
${create_dir} ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
${sarg} -d `$command +%d`/`$command +%m`/`$command +%Y`-`$command +%d`/`$command +%m`/`$command +%Y` -o ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
check=1
#--- если сегодня первое число любого месяца кроме января
elif ([ `${ddate} +%d` -eq 1 ] && [ ${check} -ne 1 ] && [ `${ddate} +%m` -ne 1 ])
then
${create_dir} ${dst}/`$command +%Y`/`$command +%m`/month
${sarg} -d 01/`$command +%m`/`$command +%Y`-`$command +%d`/`$command +%m`/`$command +%Y` -o ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
${create_dir} ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
${sarg} -d `$command +%d`/`$command +%m`/`$command +%Y`-`$command +%d`/`$command +%m`/`$command +%Y` -o ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
#--- любое число кроме 1
elif [ `${ddate} +%d` -ne 1 ]
then
${create_dir} ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
${sarg} -d `${ddate} -v-1d +%d/%m/%Y`-`${ddate} -v-1d +%d/%m/%Y` -o ${dst}/`${command} +%Y`/`${command} +%m`/`${command} +%d`
fi
Попросили у меня совета как можно найти в папке созданные 10 дней назад файлы и удалить их. Подумав у меня родилась вот такая простенькая функция:
Function Search-OldFiles {
param ($day,$path,[switch]$search)
$help = @"
`n
`t Надо использовать следующий синтаксис функции:
`t -day - задаем кол-во дней
`t -path - указываем путь
`t -search - указываем, что необходимо только найти файлы (по умолчанию они удаляются)
`t------------------------------------------------------------------------------------
`t Пример:
`t Search-OldFiles -day 2 -path 'D:\Games' -search
"@
#--- проверяем существование параметров функции
if (!($day) -or !($path) ) {write-warning $help; return}
#--- рукурсивно просматриваем папки и выбираем файлы
foreach ($item in Get-ChildItem -LiteralPath $path -Recurse -Force | Where-Object {!$_.PSIsContainer}) {
#--- сравниваем дату создания файла
if ((Get-Date).adddays(-$day) -ge $item.CreationTime) {
#--- в зависимости от ключа search просто ищем или удаляем
if ($search) { '"' + $item.fullname + '"' }
else { $item.fullname | Remove-Item -Force -WhatIf }
}
}
}
Начнем с MySQL. С ним оказалось не все так просто. Для работы с ним необходимо на компьютер где будет работать функция/скрипт установить Connector/Net от MySQL соответствующий версии вашего сервера. Прочитав доку в общем получается одна функция для select/inserd/delete/update.
Function Connect-ToMySQL {
param([String]$query,[String]$database,[String]$hostmysql,[String]$login,[String]$password)
#--- загрудаем компоненты mysql
[void][system.reflection.Assembly]::LoadWithPartialName("MySql.Data")
#--- открываем подключение
$connStr = "server=$hostmysql;port=3306;uid=$login;pwd=$password;database=$database;Pooling=False"
$conn = New-Object MySql.Data.MySqlClient.MySqlConnection($connStr)
$conn.Open()
#--- создаем объекты для выполнения запроса
$cmd = New-Object MySql.Data.MySqlClient.MySqlCommand($query, $conn)
$da = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($cmd)
$ds = New-Object System.Data.DataSet
#--- получение запроса
$da.Fill($ds) | Out-Null
#--- ну и вывод на экран
$ds.Tables[0]
#--- закрываем подключени
$conn.close()
}
В итоге получаем вот такой результат:
[PS] <16> C:\Bin>$inquiry = 'SELECT `domain-id`,username,active FROM users WHERE username="abigor@isea.ru"'
[PS] <17> C:\Bin>Connect-ToMySQL -database 'mail-server' -login 'usertest' -password 'pass' -hostmysql 'sqlsrv' -query $inquiry
domain-id username active
--------- -------- ------
1 abigor@isea.ru true
[PS] <18> C:\Bin>
[PS] <18> C:\Bin>$inquiry = 'update users set active="false" WHERE username="abigor@isea.ru"'
[PS] <19> C:\Bin>Connect-ToMySQL -database 'mail-server' -login 'usertest' -password 'pass' -hostmysql 'sqlsrv' -query $inquiry
[PS] <20> C:\Bin>$inquiry = 'SELECT `domain-id`,username,active FROM users WHERE username="abigor@isea.ru"'
[PS] <21> C:\Bin>Connect-ToMySQL -database 'mail-server' -login 'usertest' -password 'pass' -hostmysql 'sqlsrv' -query $inquiry
domain-id username active
--------- -------- ------
1 abigor@isea.ru false
[PS] <22> C:\Bin>
Все бы хорошо. но есть одна проблема. Если у вас запрос в стоит в апострофе, то экранировать имена полей с дефисом надо одинарными обратным апострофом
. Если же в запрос взят в кавычки, то экранировать надо двумя обратными апострофами
. Понятно почему так получается. Из-за того, что все кавычки позволяют раскрыть содержимое, а все что в апострофах воспринимается как текст.