понедельник, 14 апреля 2014 г.

Парсинг и вывод заданным форматом всех .xml файлов, начиная с указанной директории

1) Написать команду или скрипт, просматривающий все *.xml файлы в директории.

Формат файлов:

<FirstName>john</FirstName>
<MiddleInitial>D</MiddleInitial>
<LastName>Smith</LastName>

<Delivered>
<Date>2014-01-31</Date>
</Delivered>

Имена могут иметь пробелы, верхний или нижний регистр, включать - или '.

Необходимо пропарсить все файлы и вывести данные в файл:

firstname middleinitial lastname | delivered date | filenameitwaslocated.xml
firstname middleinitial lastname | delivered date | filenameitwaslocated.xml


1.1) Разбираю несколько примеров, вот один из них:

grep -v ^[[:space:]]*\# $1 | grep -v ^[[:space:]]*\; | grep -v ^$

^ - начало строки
$ - конец строки
[:space:] - соответствует пробельным символам (пробел и горизонтальная табуляция)
[] - один из символов, указанных в скобках

в чем отличие ? от . - в том что точку можно указать просто, а вопрос надо экранировать, иначе он воспринимается как символ вопрос

2) Пишу свой скрипт.

2.1) Создаю файл с данными:
#   3
  ##
<FirstName>j o h n</FirstName>
<MiddleInitial>-D-</MiddleInitial>
<LastName>S-mith'</LastName>

<Delivered>
<Date>2014-01-31</Date>
</Delivered>

2.2) Затем в исполняемый файл пишу команду и передаю параметром файл данных:

/bin/echo `grep -o '>.*<' $1 | sed 's/<\|>//g'`
выдает
j o h n -D- S-mith' 2014-01-31
как теперь сделать
j o h n -D- S-mith' | 2014-01-31 | filenameitwaslocated.xml

echo `grep -o '>.*<' $1`"$1"|(sed 's/>\(.*\)<.>\(.*\)<.>\(.*\)<.>\(.*\)<\(.*\)/\1 \2 \3 | \4 | \5/')
выдает
j o h n -D- S-mith' | 2014-01-31 | cat_xml.input

2.3) написать что ли как оно работает...

grep построчно парсит файл, передаваемый параметром $1
-o - выдавать только то что соответствует шаблону
получаются строки вида >то_что_между<
echo убирает с конца каждой строки перевод на новую строку, выдает все строки одной строкой и добавляет в конец имя переданного файла "$1"
sed парсит строку по шаблону />\(.*\)<.>\(.*\)<.>\(.*\)<.>\(.*\)<\(.*\)/ и возвращает 5 значений (.*\), которые я потом вывожу, форматируя /\1 \2 \3 | \4 | \5/

2.4) Двигаюсь дальше. Создаю несколько файлов *.xml

find ./ -name '*.xml' -exec ./cat_xml {} > ./output \;
cat ./output
4 o h n -D- S-4mith' | 2014-01-34 | ./cat_xml4.xml
55j o h n 55 S-mith55' | 2014-01-35 | ./cat_xml5.xml
j o h n2 D- Smith' | 2014-01-32 | ./cat_xml2.xml
4 o h n -D- S-4mith' | 2014-01-34 | ./222/cat_xml4.xml
55j o h n 55 S-mith55' | 2014-01-35 | ./222/cat_xml5.xml
j o h n2 D- Smith' | 2014-01-32 | ./222/cat_xml2.xml
j o h n -D- S-mith' | 2014-01-31 | ./222/cat_xml1.xml
j3o3h3n D3 S-mith3 | 2014-01-33 | ./222/cat_xml3.xml
j o h n -D- S-mith' | 2014-01-31 | ./cat_xml1.xml
j3o3h3n D3 S-mith3 | 2014-01-33 | ./cat_xml3.xml

3) Использованные ресурсы:
http://rus-linux.net/MyLDP/BOOKS/abs-guide/flat/abs-book.html
http://citforum.ru/operating_systems/manpages/bash/BASH.1_2.shtml#expansion
http://www.theunixschool.com/2013/02/sed-examples-replace-delete-print-lines-csv-files.html
http://unix.stackexchange.com/questions/64645/text-between-two-tags
http://stackoverflow.com/questions/8476329/get-string-between-and-linux-directory

среда, 2 апреля 2014 г.

Full backup of CentOS 6.5 on IBM System x3650 M4


Использую книгу М. Кофлер "Linux. Установка, настройка, администрирование" 2013 года (далее - книгу), в основном Главу 25 Резервное копирование.
http://rutracker.org/forum/viewtopic.php?t=4617248

Для начала инсталлирую еще один архиватор:
# yum install lzop

Устанавливаю и настраиваю webmin, т. к. там есть Filesystem Backup.


1) Обзор вариантов резервирования.

1.1) Образ загрузочного тома и других (которые не LVM).
Создается и восстанавливается с помощью dd:
# dd if=/dev/sda1 of=/backup/boot.dd

1.2) Образ LVM-тома.
Создается снапшот, затем cat snapshot сжимается в image.lzo (в книге есть пример).
Попробовал вместо cat использовать dd для чтения тома LVM - результат одинаков.

1.2.1) Для чего делают бакап образом?
Если, к примеру, данные на томе - это образ виртуальной машины. Если утрировать: том со свапом не сархивировать, его можно забакапить лишь образом.
Видел в инете инструкцию, где, используют исталляционный диск и устанавливают систему с такого файла-образа (Debian).

1.2.2) Провел тест считывания образа логических томов LVM:

# time cat /dev/vg01/lv_home > /mnt/squid/lv_home.img
real    7m31.971s
-rw-r--r--  1 root   root   53687091200 Feb 26 10:50 lv_home.img

# time cat /dev/vg01/lv_home | lzop -c > /mnt/squid/lv_home.img.lzo
real    3m39.066s
-rw-r--r-- 1 root root 223889323 Feb 26 11:00 lv_home.img.lzo

Вывод: просто считанный файл-образ получается размером с том, хотя данных 200 МБ, а со сжатием намного эффективнее.

1.2.3) Как восстанавливать с образа?

1.2.3.1) Так восстанавливают прямо со снапшота (инет): # dd if=/dev/vg00/lv_root_snap of=/dev/vg00/lv_root

1.2.3.2) Я попробовал считать (как указано выше п.1.2.2) и аналогично записать образ /home обратно, и это сработало:

# umount /home
# mkfs.ext4 /dev/vg01/lv_home (форматирую, чтобы стереть все данные)
# lzop -dc /mnt/squid/lv_home.img.lzo > /dev/vg01/lv_home
# mount /home

1.3) Архив LVM-тома.
Создается снапшот, затем содержимое снапшота сжимается в tar.gz (в книге есть пример).

1.3.1) Как сохранить конфигурацию LVM? Чтобы создать такие же группу и тома для восстановления.
Ежедневная резервная копия должна включать содержимое каталога /etc/lvm.
Создать архив метаданных в /etc/lvm/backup можно с помощью команды vgcfgbackup. Восстановить метаданные можно с помощью vgcfgrestore.


2) Резервирование.

2.1) Для начала разделил то "что надо резервировать", то "что не надо" и "куда резервировать" на отдельные тома.
$ df -h
Filesystem                  Size  Used Avail Use% Mounted on
/dev/mapper/vg01-lv_root     50G  3.6G   44G   8% /
tmpfs                        16G     0   16G   0% /dev/shm
/dev/sda2                   485M   67M  394M  15% /boot
/dev/sda1                   200M  260K  200M   1% /boot/efi
/dev/mapper/vg01-lv_squid   148G   91G   50G  65% /mnt/squid
/dev/mapper/vg01-lv_home     50G  196M   47G   1% /home
/dev/mapper/vg01-lv_log      50G  445M   47G   1% /var/log
/dev/mapper/vg01-lv_mysql    99G  224M   94G   1% /var/lib/mysql
/dev/mapper/vg01-lv_www     197G  8.6G  179G   5% /var/www
/dev/mapper/vg01-lv_backup  296G   52G  229G  19% /mnt/backup

2.2) Схема создания архива LVM-тома:
- Создавать снапшот
- Создавать архив (можно Filesystem Backup в webmin)
- Удалять снапшот

2.2.1) Написал скрипт создания снапшота.

# cat ./create_snap_before_backup
#!/bin/bash

# Если не переданы имя снапшота и расширение архива, то выход
if test $# -ne 2; then
  echo "Enter name of snapshot and archive extention"
  exit 1
fi

# Указываю значение переменных
snap_name="${1}_snap"
archive_ext=$2
backup_path="/mnt/backup"
snap_lv="/dev/vg01/$snap_name"
lv="/dev/vg01/lv_$1"
log="$backup_path/$snap_name.log"

# Логирую начало запуска скрипта
echo "BEGINING $0 for $snap_name.$archive_ext" &>> $log
date &>> $log
echo "" &>> $log

# Создаю директорию для монтирования снапшота
# -p  no error is existing
mkdir -p "$backup_path/$snap_name"

# Создаю снапшот и монтирую
lvcreate -s -L 1G -n $snap_name $lv &>> $log
mount -t ext4 $snap_lv "$backup_path/$snap_name" &>> $log

# Делаю ротацию архивов (4 штуки)
for i in 2 1 0; do
  if test $i -ne 0; then j=$i; i=$[$j+1]
  else j=''; i=1; fi

  if test -f "$backup_path/$snap_name$j.$archive_ext"; then
    mv -f "$backup_path/$snap_name$j.$archive_ext" "$backup_path/$snap_name$i.$archive_ext" &>> $log; fi
done

2.2.2) Написал скрипт удаления снапшота.

# cat ./remove_snap_after_backup
#!/bin/bash

# Если не передан параметр название снапшота, то выход
if test $# -ne 1; then
  echo "Enter name of snapshot"
  exit 1
fi

# Устанавливаю значения переменных
snap_name="${1}_snap"
backup_path="/mnt/backup"
snap_lv="/dev/vg01/$snap_name"
log="$backup_path/$snap_name.log"

# Удаляю снапшот с логированием в файл-лог
lvdisplay $snap_lv &>> $log
umount "$backup_path/$snap_name" &>> $log
lvremove -f $snap_lv &>> $log

# Логирую окончание процесса резервирования
date &>> $log
echo "ENDING $0 $snap_name Backup" &>> $log
echo "" &>> $log
echo "" &>> $log


2.2.3) In Webmin Filesystem Backup делаю Add a new backup of directory.

2.2.3.1) Для /var/www
Directories to backup /mnt/backup/www_snap
Backup to /mnt/backup/www_snap.tgz
Compress archive? yes, with gzip
Command to run before backup /home/sergeiki/bin/create_snap_before_backup www tgz
Command to run after backup /home/sergeiki/bin/remove_snap_after_backup www
Scheduled backup enabled? Enabled, at times chosen below.. Sunday 3:00

2.2.3.2) Для /
Directories to backup /mnt/backup/root_snap
Backup to /mnt/backup/root_snap.tgz
Files and directories to skip /boot /mnt/backup /mnt/squid /home /var/lib/mysql /var/log /var/www /sys /proc
Compress archive? yes, with gzip
Limit backup to one filesystem? No
Ignore read errors on files? Yes
Command to run before backup /home/sergeiki/bin/create_snap_before_backup root tgz
Command to run after backup /home/sergeiki/bin/remove_snap_after_backup root
Scheduled backup enabled? Enabled, after: /mnt/backup/www_snap to /mnt/backup/root_snap.tgz

2.2.3.2.1) Попробовал резервировать lv_root с исключением подмонтированного (Limit backup to one filesystem? Yes), много каталогов не забакапилось.
Я рассчитывал, что это будут /home, /mtn/*, /var/log и т.д. как мне и надо, но не забакапились и /dev, /proc, /sys...
Поэтому, указываю резервировать с подмонтированным, но исключаю /boot /mnt/backup /mnt/squid /home /var/lib/mysql /var/log /var/www /sys /proc

2.2.3.3) И т.д. для остальных LVM-томов.


2.2.4) Написал скрипт, создающий архивы образов /boot, /boot/efi, / и поставил его в cron на Sunday 2:00.

# cat ./create_snap_image |more
#!/bin/bash

# Путь для резервных копий
backup_path="/mnt/backup"

# Задаю имя логического диска, файл-лог, расширение архива
snap_name="sda1"
log="$backup_path/$snap_name.log"
archive_ext="gz"

# Логирую начало
echo "BEGINING $0 for $snap_name.$archive_ext Backup (/boot/efi)" &>> $log
date &>> $log
echo "" &>> $log

# Делаю ротацию архивов (4 штуки)
for i in 2 1 0; do
  if test $i -ne 0; then j=$i; i=$[$j+1]
  else j=''; i=1; fi

  if test -f "$backup_path/$snap_name$j.$archive_ext"; then
    mv -f "$backup_path/$snap_name$j.$archive_ext" "$backup_path/$snap_name$i.$archive_ext" &>> $log; fi
done

# Создаю архив образа логического тома и делаю запись в лог
(dd if=/dev/sda1 | gzip -c > $backup_path/$snap_name.$archive_ext) &>> $log
echo "" &>> $log

# Логирую окончание
date &>> $log
echo "ENDING $0 $snap_name Backup (/boot/efi)" &>> $log
echo "" &>> $log
echo "" &>> $log


snap_name="sda2"
log="$backup_path/$snap_name.log"
archive_ext="gz"

echo "BEGINING $0 for $snap_name.$archive_ext Backup (/boot)" &>> $log
date &>> $log
echo "" &>> $log

for i in 2 1 0; do
  if test $i -ne 0; then j=$i; i=$[$j+1]
  else j=''; i=1; fi

  if test -f "$backup_path/$snap_name$j.$archive_ext"; then
    mv -f "$backup_path/$snap_name$j.$archive_ext" "$backup_path/$snap_name$i.$archive_ext" &>> $log; fi
done

(dd if=/dev/sda1 | gzip -c > $backup_path/$snap_name.$archive_ext) &>> $log
echo "" &>> $log

date &>> $log
echo "ENDING $0 $snap_name Backup (/boot)" &>> $log
echo "" &>> $log
echo "" &>> $log


snap_name="root_snap"
log="$backup_path/$snap_name.log"
archive_ext="lzo"

echo "BEGINING $0 for $snap_name.$archive_ext Backup" &>> $log
date &>> $log
echo "" &>> $log

for i in 2 1 0; do
  if test $i -ne 0; then j=$i; i=$[$j+1]
  else j=''; i=1; fi

  if test -f "$backup_path/$snap_name$j.$archive_ext"; then
    mv -f "$backup_path/$snap_name$j.$archive_ext" "$backup_path/$snap_name$i.$archive_ext" &>> $log; fi
done

# Создаю снапшот (т. к. это LVM-том, а не обычный, как два предыдущих sda1 и sda2)
/sbin/lvcreate -s -L 1G -n $snap_name /dev/vg01/lv_root &>> $log

echo "" &>> $log
(dd if=/dev/vg01/root_snap | lzop -c > $backup_path/$snap_name.$archive_ext) &>> $log
echo "" &>> $log

# Удаляю снапшот
/sbin/lvremove -f /dev/vg01/root_snap &>> $log
echo "" &>> $log

date &>> $log
echo "ENDING $0 $snap_name Backup" &>> $log
echo "" &>> $log
echo "" &>> $log

вторник, 1 апреля 2014 г.

AdSense and Blogger

1) В Blogger меню Прибыль / AdSense все время вижу сообщение:

Ваш блог не соответствует правилам программы AdSense.

Пытался решить наскоком - не вышло, попробую записать, чтобы разобраться.

Следую Подробнее...
Далее в меню справа Если вам нужно несколько аккаунтов AdSense.
Следую Подробнее о добавлении сайтов...
Далее создать код AdSense.
Если нет рекламных блоков - создать, следуя подсказкам, если есть, то Получить код.

1.1) В окне получения кода - Руководство по внедрению кода.

Далее в меню справа Вставка рекламного кода на страницу.
Затем Использование системы управления контентом (CMS).
Далее Blogger из Сайты со встроенным кодом AdSense.

Используя AdSense, вам не придется выбирать ключевые слова или категории для объявлений. Мы сами определим тематику вашего блога и будем отображать в нем рекламу соответствующего содержания.

У Blogger должен быть доступ к вашему аккаунту AdSense, чтобы мы могли автоматически создавать рекламный код и размещать его в блоге, используя собственные шаблоны и инструменты дизайна.

AdSense, "Главная страница", "Настройки аккаунта", пункт "Доступ третьих сторон" - ничего не отображает...

Проверил все настройки AdSense - вроде бы всё нормально...

Вывод: покуда Ваш блог не соответствует правилам программы AdSense как ни старайся, ничего не отобразится?..
И, судя по хелпу, Blogger должен сам управлять привязанным к нему аккаунтом AdSense...

1.2) Попробовал получить код и вставить вручную.

Изменил шаблон, смотрю исходный код страницы в браузере - изменения присутствуют, но ничего не отобразилось...

Получилось! Код, вставленный в шаблон, отображается если смотреть блог другими браузерами...
Возможно, срабатывает настройка исключения меня из статистики посещений (установленный cookie блокирует и рекламу).
Убрал эту настройку - всё равно реклама в этом браузере не отобразилась, возможно из-за того, что с браузера был вход в google...
Дошло - Adblock Plus.

Найдено решение.
В меню Дизайн добавляю гаджет HTML/JavaScript, а в него добавляю рекламный код AdSense.


P.S. The End of history THERE.