Некоторые картинки не загружаются из РФ и РК, используйте VPN.

вторник, 3 января 2023 г.

Bash script WOL для списка

На одном из объектов бэкап построен на базе bash скриптов, списком копируемых к нему выступает файл с таким содержимым:
user@server:~$ head -n 2 /opt/scripts/backup/compoff.txt
#Номер;Имя ПК;имя пользователя;айпи (не обязательно);мак адрес;выключать или нет
1;AIVANOV;aivanov;10.21.2.140;D8:BB:C1:5B:6E:5D;1

Собственно сам скрипт обходит список, шлет WOL, ожидает и проверяет по пингу включился ли ПК, если да, то помещается в массив для обработки, иначе репорт на почту. Хорошо работает вот уже лет 7. Но иногда есть потребность во включении определенного ПК из этого списка, и дабы автоматизировать поиск, отправку WOL и проверку, написал скрипт. Также нужно учесть то, что компьютеры находятся в разных сегментах сети, поэтому посыл будет с двух серверов.

Условия:

  1. наличие wakeonlan на всех причастных серверах
  2. ssh ключи на причастных серверах (не рут)
Собственно сам скрипт:
#!/bin/bash
compofftxt="/opt/scripts/backup/compoff.txt"
#Домен нужен для пинга
domen="domen.ru"

# Функция wol на входе имеет массив мак адресов. Обходит их и отправляет команду wakeonlan. Быстрее было бы отправить на второй сервер массив, но так не красиво
function wol {
	local macArray="$@"
	if [ -n "$macArray" ]
	then
		echo -e "\n\e[33mMAC list processing...\e[37m"
		for mac in ${macArray[*]}
		do
			echo "  Fnode1: " | tr -d '\n'
			wakeonlan $mac
			echo "  Fnode2: " | tr -d '\n'
			ssh fnode2 wakeonlan $mac
			echo ""
		done
	else
		echo "Array is empty!"
	fi

}

echo -e "\n\e[33mScript WOL.sh is run\e[37m"

# Если аргументов 0, тогда спросим у пользователя, может надо включить все компьютеры?
# Соответственно источником для формирования списка MAC адресов будет выступать или сам файл или патерны из аргументов
if [ $# -eq 0 ]
then
	echo -e "\e[31mTemplate not set!\e[37m"
	read -p $'\e[33mDo you want to run wake on lan for all PC? (y/n)[n]: \e[37m' answer

	if [[ "$answer" = "y"  || "$answer" = "Y" ]]
	then
		echo "\e[33mRun WOL\e[37m"
		source=$(grep -v "#" $compofftxt)
		allWOL=1
	else
		echo -e "\e[31mCancle\e[37m\n"
		exit
	fi
else
	echo -e "\e[33mGot $# pattern\e[37m"
	source="$@"
	allWOL=0
fi

# Формируем список MAC адресов
MacArray=()
for str in ${source[*]}
do
	if [ $allWOL -eq 0 ]
	then
		pattern=$str
		mac=`grep -v "#" $compofftxt | grep -i $pattern -m 1 | awk -F";" '{print $5}'`
		name=`grep -v "#" $compofftxt | grep -i $pattern -m 1 | awk -F";" '{print $2}'`
	else
		mac=`echo $str | awk -F";" '{print $5}'`
		name=`echo $str | awk -F";" '{print $2}'`
	fi
	if [ -n "$mac" ]
	then
		echo "  Pattern \"$pattern\" returned \"$name\" with MAC=\"$mac\""
		MacArray+=("$mac")
	else
		echo "  Pattern \"$pattern\" didn\`t return anything"
	fi
done

# Отправляем список MAC адресов функции wol
if [ "${#MacArray[*]}" -gt 0 ]
then
	echo -e "\e[33mFound ${#MacArray[*]} MAC address\e[37m"
	wol ${MacArray[*]}
else
	echo -e "\e[33mExit\e[37m\n"
	exit
fi

# Спрашиваем, нужна ли проверка?
# При проверке мы опять обращаемся к файлу, но патерном выступает именно MAC адрес. Можно изначально формировать список имя-MAC, но мне лень
read -p $'\e[33mDo you want check wake up PC? (y/n)[n]: \e[37m' answer
if [[ "$answer" = "y"  || "$answer" = "Y" ]]
then
# вот это простенький таймер, компам даже на SSD нужно секунд 30 на включение
	for ((i=30;i>=0;i--))
	do
		printf "\e[33mWait: %02d sec\r\b\e[37m" $i
		sleep 1
	done
       echo -e "\n\e[33mState PC:\e[37m"
	for str in ${MacArray[*]}
	do
		name=`grep -v "#" $compofftxt | grep -i $str -m 1 | awk -F";" '{print $2}'`
		if [ -n "$name" ]
		then
			ping -c 3 "$name.$domen">/dev/null 2>/dev/null
			erping=$?
			if [ $erping -eq 0 ]
			then
				echo -e "       \e[32m$name PC is on \e[37m"
			else
				echo -e "       $name PC is off"
			fi
		fi
	done
	echo -e "\e[33mExit\e[37m\n"
else
	echo -e "\e[33mExit\e[37m\n"
fi

Не обошлось без свистоперделок в виде цветного вывода. Собственно скрипт выкладываю как шпаргалку по следующим вопросам:

  1. Запрос ввода от пользователя (аналог для Mikrotik)
  2. Перенаправление вывода (ping -c 3 "$name.$domen">/dev/null 2>/dev/null)
  3. Обработка кода возврата ($?)
  4. Операторы сравнения, в т.ч. AND/OR (&&/||)
  5. Работа с функциями
  6. Работа с массивами, в т.ч. передача функции
  7. Покраска текста
  8. Таймер
Также можно, прикола ради, чуть дописать скрипт так, чтобы его можно было запускать смской через wAP LTE и получать ответ.

Комментариев нет:

Отправить комментарий