Иногда требуется управлять множеством IP-адресов на множестве компьютеров в сети. Для такого случая я написал скрипт в помощь. Использование его очень простое:
Результатом работы скрипта будет удаление ненужных, а затем добавление новых IP-адресов.
Внимание: если в файле не будет указан какой-либо локальный интерфейс, операции с ним производиться не будут! Для решения этого, достаточно указать для всех интерфейсов хотя бы один, первичный, IP-адрес, даже если он не будет меняться.
Требования: установленные bash и iproute2.
Для запуска скрипта в режиме тестирования (без реального изменения состояния интерфейсов), запускайте скрипт с ключом -t.
#!/bin/bash
dir="$(dirname $0)"
ipfile="ip.list"
hostname="$(hostname -f)"
tmpdir='/tmp'
test=false
while getopts 't' opt; do
case $opt in
't')
test=true
;;
esac
done
function ipsort()
{
sort -n -t'.' -k1,1 -k2,2 -k3,3 -k4,4
}
declare iflist=''
declare -A ifpri=()
declare -A ifsec=()
while read ip host iface default; do
if [ -n "$ip" ] && [ -n "$host" ] && [ -n "$iface" ] && [ "$host" = $hostname ]; then
[ ${ip:0:1} = '#' ] && continue
[ -z "$(echo -n $iflist | grep -w $iface)" ] && iflist="$iflist $iface"
[ -z "$(echo $ip | grep '/')" ] && ip="$ip/32"
[ -n "$default" ] &&
ifpri[$iface]="$ip" ||
ifsec[$iface]="${ifsec[$iface]} $ip"
fi
done < $ipfile
declare -a cmddel=()
declare -a cmdadd=()
for iface in $iflist; do
tmpprefix="$tmpdir/$iface"
ip addr show | grep -w $iface | grep -w 'inet' | cut -d' ' -f6 | ipsort > ${tmpprefix}_cur
(
[ -n "${ifpri[$iface]}" ] &&
echo ${ifpri[$iface]} ||
echo -n
) | sed -e 's/\s/\n/' | ipsort > ${tmpprefix}_new
(
[ -n "${ifsec[$iface]}" ] &&
echo ${ifsec[$iface]} ||
echo -n
) | sed -e 's/\s/\n/' | ipsort >> ${tmpprefix}_new
diflist="$(diff ${tmpprefix}_cur ${tmpprefix}_new | awk '$1=="<" || $1==">" { print $1$2 }')"
if [ -n "$diflist" ]; then
for difline in $diflist; do
action=${difline:0:1}
ip=${difline:1}
case $action in
'<')
cmddel[${#cmddel[@]}]="ip addr del $ip dev $iface"
;;
'>')
cmdadd[${#cmdadd[@]}]="ip addr add $ip dev $iface"
;;
*)
echo "Error: unknown action $action!"
esac
done
fi
done
n=${#cmddel[@]}
while [ $n -gt 0 ]; do
n=$(($n-1))
echo ${cmddel[$n]}
$test || eval ${cmddel[$n]}
done
n=${#cmdadd[@]}
while [ $n -gt 0 ]; do
n=$(($n-1))
echo ${cmdadd[$n]}
$test || eval ${cmdadd[$n]}
done
192.168.0.1/24 firsthost eth0 192.168.0.2/24 secondhost eth0 192.168.1.1/24 secondhost eth1 192.168.1.2 secondhost eth1
При запуске скрипта setip.sh на компьютере secondhost будут произведены следующие действия в указанном порядке:
Дискуссия