Бэкапы виртуальных машин в VMWare ESXi

Как не странно, но это действительно большая проблема, так как специальных утилит для этого нет, а то что есть немного мудрено, ведь можно сделать проще:

#!/bin/sh

sourcedir=/vmfs/volumes/datastore1
backupdir=/vmfs/volumes/nfs-backup

for i in `vim-cmd vmsvc/getallvms|awk '{print($1 "-" $2)}'`; do
if [ $i != "Vmid-Name" ]; then
vmid=${i%%-*}
vmfs=${i#*-}

mkdir $backupdir/$vmfs.`date +%d.%m.%Y`
vim-cmd vmsvc/snapshot.create $vmid $vmfs@snap $vmfs@snap includeMemory 0
for j in `ls $sourcedir/$vmfs`; do
cat $sourcedir/$vmfs/$j | gzip > $backupdir/$vmfs.`date +%d.%m.%Y`/$j.gz
done
vim-cmd vmsvc/snapshot.removeall $vmid
fi
done

cd $backupdir; find . -type d -mtime +5 -exec rm -rf {} \;

/vmfs/volumes/nfs-backup – соответственно nfs диск где будут лежать бэкапы
/vmfs/volumes/datastore1 – хранилище виртуальных машин

Bash Считываем файл построчно

И так, в bash-е, для того, что бы считать файл построчно:

#!/bin/bash
file="/home/osticket/data.txt"
while IFS= read -r line
do
# display $line or do somthing with $line
echo "$line"
done <"$file"

или

#!/bin/bash
file="/home/osticket/data.txt"
while read line
do
# display $line or do somthing with $line
echo "$line"
done < $file

Строка будет записываться в переменную $line

Bash Считам количество букв в строке

И так, для подсчета количества букв воспользуемся командой grep. Как пример давайте посчитает количество букв ‘s’ в переменной $x:

x=»This is a test»
grep -o «s» <<<«$x» | wc -l

результат будет:

3

Для того, что бы посчитать ‘s’ и ‘S’:

x=»This is a test. S»
grep -o «[s|S]» <<<«$x» | wc -l

результат:

4

Используя только bash:

x=»This is a test»
y=»${x//[^s]}»
echo «$y»
echo «${#y}»

Для того, что бы посчитать ‘s’ и ‘S’:

x=»This is a test. S»
y=»${x//[^s|S]}»
echo «${#y}»

Bash Удаляем пустые папки

Тут на медне у меня ушли в мир иной пара винтов на сервере, которые были в одной LVM разделе. Бакапы давно никто не снимал, а информация с них была нужна. В общем после восстановления раздела, и проходы по нему fsck-ом, образовалась масса папочек, и многие из них были пустыми, так вот, что бы удалить все пустые папки, вы можете воспользоваться следующим:

find -depth -type d -empty -exec rmdir {} \;

Bash скрипт ротации файлов

Данный скрипт поддерживает историю за последние 7 дней. Как пример, tar-ом будем упаковывать папку /var/www/repository  и удалить все файлы старше 7 дней.

#!/bin/bash
# Date
fecha=`date +"%d-%m-%Y"`
# Backup and gzip the directory
tar zcvf /back/trunk-$fecha.tgz /var/www/repository
# Rotate the logs, delete older than 7 days
find /backups/ -mtime +7 -exec rm {} \;

Нотариусы Москвы — сайт, где есть все нотариусы.

Bash Ждать пока не завершится процесс

Бывает, что в bash скрипте необходимо подождать пока не завершиться какой-то процесс. Если вы знаете его pid, то это можно реализовать так:

while ps -p `cat $PID_FILE` > /dev/null; do sleep 1; done

Bash скрипт универсальный распаковщик

Надоело мне для каждой программы сжатия использовать свои программы и ключи, и вылился этот порыв вот в такой скрипт:

#!/bin/bash
#
#

Z="compress -d"
gz="gunzip"
bz="bunzip2"
zip="unzip -qo"
rar="unrar x -id -y"
tar="tar xf"
7z="p7zip -d"

if [ $# -eq 0 ]; then
    echo "Usage: decompress file or files">&2
    exit 1
fi

for name
do
	if [ ! -f "$name" ] ; then
		echo "$0: file $name not found." >&2
		continue
	fi

	if [ "$(echo $name | egrep '(\.Z$|\.gz$|\.bz2$|\.zip$|\.rar$|\.tar$|\.tgz$|\.7z$)')" = "" ] ; then
		echo "Skipped file ${name}: it's already decompressed." 
      		continue
	fi

	extension=${name##*.}

	case "$extension" in
		Z ) echo "Filetype is Z. Decompressing..."
		    $Z "$name"
		    ;;
		gz ) echo "Filetype is gz. Decompressing..."
		     $gz "$name"
		     ;;
		bz2 ) echo "Filetype is bz2. Decompressing..."
 		     $bz "$name"
		     ;;
		zip ) echo "Filetype is zip. Decompressing..."
		      $zip "$name"
		      ;;
		rar ) echo "Filetype is rar. Decompressing..."
		      $rar "$name"
		      ;;
		tar ) echo "Filetype is tar. Decompressing..."
              	      $tar "$name"
              	      ;;
		tgz ) echo "Filetype is tgz. Decompressing..."
              	      $tar "$name"
                     ;;
               7z ) echo "Filetype is 7z. Decompressing..."
                     $7z "$name"
	esac

done

exit 0


Bash Убираем коментарии в файле

Я думаю каждый администратор сталкивался с такой проблемой, когда нужно убрать все закоментированые строки в конфигурационном файле или скрипте. Для этого вы можете воспользоваться вот таким скриптом:

#!/bin/bash
#
#
sed '1p; /^[[:blank:]]*#/d; s/[[:blank:]][[:blank:]]*#.*//' $1 > new

Правда есть небольшая проблема, возникнет куча пустых строк, поэтому мы немного переделаем скрипт:

#!/bin/bash
#
#
sed '1p; /^[[:blank:]]*#/d; s/[[:blank:]][[:blank:]]*#.*//' $1 | sed -e 's/[\t ]//g;/^$/d' > new

 

Bash нюансы. Часть 2. Длинна переменной

Для того, что бы найти длину строки вы можете использовать следующий синтаксис:

#!/bin/bash
${#variableName}
echo ${#variableName}
len=${#var}

Как пример использования, небольшой скрипт для добавления FTP пользователя:

#!/bin/bash
# Usage : Add a ftp user
_fuser="$1"
_fpass="$2"

# die if username/password not provided
[ $# -ne 2 ] && { echo "Usage: addftpuser username password"; exit 1;}

# Get username length and make sure it always <= 8
[[ ${#_fuser} -ge 9 ]] && { echo "Error: Username should be maximum 8 characters in length. "; exit 2;}

# Check for existing user in /etc/passwd
/usr/bin/getent passwd "${_fuser}" &>/dev/null

# Check exit status
[ $? -eq 0 ] && { echo "Error: FTP username \"${_fuser}\" exists."; exit 3; }

# Add user
/sbin/useradd -s /sbin/nologin -m  "${_fuser}"
echo "${_fpass}" | /usr/bin/passwd "${_fuser}" --stdin

Часть 1. Значение по умолчанию для переменных
Часть 2. Длинна переменной

Bash нюансы. Часть 1. Значение по умолчанию для переменных

Не все знают, что в bash  есть возможность назначить входной переменной параметр по умолчанию. Как пример, если параметр $1 не задан то использовать root:

user=${1:-root}

Еще один пример использования:

#!/bin/bash
dir="${1:-/tmp}"
cp * $dir
echo "Все скопировано в ${dir}"

Вы так же можете назначить значение по умолчанию обычной переменной. Как пример выведем значение параметра $VAR при помощи echo, при этом, если $VAR не задан то присвоить значение parametr:

echo ${VAR:=parametr}

Важно помнить, что со специальными параметрами, такими как например $1 необходимо использовать конструкцию ${var:-defaultValue}
 

Часть 1. Значение по умолчанию для переменных
Часть 2. Длинна переменной