Скрипт парсит dhcpd.leases файл и отображает список подсетей 0/24 на выбор, после выбора подсети выдается список арендованных ip со статусом free или active, где можно выбрать один или несколько ip и удалить.
Скрипт использует dialog, за счет чего меню получается очень привлекательным :) - писал под FreeBSD, на Linux не тестировал (возможно будут проблемы из-за несовместимости BSD awk и GNU awk), хотя думаю, что должен работать и под Linux.
Скрипт использует dialog, за счет чего меню получается очень привлекательным :) - писал под FreeBSD, на Linux не тестировал (возможно будут проблемы из-за несовместимости BSD awk и GNU awk), хотя думаю, что должен работать и под Linux.
#!/bin/sh # загружаем /etc/rc.conf. . /etc/rc.conf #TODO - установить имя файла более точнее, см. /usr/local/etc/rc.d/isc-dhcpd. file=${dhcpd_rootdir}/var/db/dhcpd/dhcpd.leases tempfile=$(mktemp 2>/dev/null) || tempfile=/tmp/$(basename $0)_$$ trap "rm -f $tempfile" 0 1 2 5 15 ### functions: BEGIN # Функция запуска команд в информационном окошке. exec_fun() { dialog --sleep 1 --title "$2" \ --msgbox "`echo ;$1 2>&1;echo`" 15 85 } # Функция удаления lease. del_lease() { exec_fun "service isc-dhcpd stop" "Status Daemon:" #TODO - убедиться, что демон остановлен. # Бекап базы. DATE=$(date "+%Y%m%d%H%M") cp $file ${file}.$DATE for i in $1; do awk 'BEGIN { FLG=0; } { if ($0=="lease '$i' {") FLG=1; if (FLG=="0") printf "%s",$0"\n"; if ($0=="}" && FLG=="1") FLG=0; }' $file > ${file}.new mv ${file}.new $file done [ -f "${file}~" ] && rm -f "${file}~" exec_fun "service isc-dhcpd start" "Status Daemon:" #TODO - убедиться, что демон запущен. } # Функция получения списка subnet из dhcpd.leasees файла. get_subnet_list() { grep -oE '^lease [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.' $file | sort -u \ | awk 'BEGIN { n=1; }{ print n" "$2"0/24 off"; n++; }' } # Функция получения списка ip по subnet'у /24 и вывод списка в виде dialog. get_leases() { while [ true ]; do LIST=`awk '{ out=""; sub(/[;#].*/,"",$0); \ if ($1" "$2" "$3 ~ /^lease '$(echo $1 | sed 's|\.|\\.|g')'[0-9]?[0-9]?[0-9] \{$/ ) { out=" "$2; FLG=1; } \ if ($1=="binding" && FLG=="1") out=" "$3; \ if ($1=="}" && FLG=="1") { out="\n"; FLG=0; } \ printf out," "; }' $file | \ sort -un -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 | \ awk 'BEGIN { n=1; }{ print n" \""$1" "$2"\" off"; n++; }'` DIALOG='dialog --backtitle "Редактирование '$file'" --cancel-label Back --ok-label Delete --title "Редактирование '$1'0/24" --clear --checklist "Выбор lease" 20 61 10 '$LIST' 2> '$tempfile eval $DIALOG # Собственно удаление выбранных lease. $(cat $tempfile) if [ "$?" -eq 0 ]; then # Формируем и передаваем в функцию удаления список ip. DEL_LIST='' for i in $(cat $tempfile); do DEL_LIST="$DEL_LIST "`echo "$LIST" | awk '{ if ($1=="'$i'") { sub(/0\/24$/,"",$2); sub(/"/,"",$2); print $2; }}'` done del_lease "$DEL_LIST" else break; # Выходим из while [true]. fi done } ### functions: END [ ! -f $file ] && echo 'ERROR: File "'$file'" not exist or not readable!' && exit 1 while [ true ]; do LIST="$(get_subnet_list)" dialog --backtitle "Редактирование $file" \ --cancel-label Exit \ --title "Редактирование $file" --clear \ --radiolist "Выбор subnet" 20 61 10 \ $LIST \ 2> $tempfile if [ "$?" -eq 0 ]; then `echo "$LIST" | awk '{ if ($1=="'$(cat $tempfile)'") { \ sub(/0\/24$/,"",$2); print "get_leases "$2 }}'` else break; # Выходим из while [true]. fi done