LINUX.ORG.RU
ФорумAdmin

bash - syntax error invalid arithmetic operator error token is

 ,


0

1

Приветствую! Ребята подскажите где я не догоняю?

Нужно выполнить проверку значений с первого массива во втором.

state_ip=(172.20.0.3/24 192.168.168.1/24 192.168.195.1/24 192.168.199.1/24)
current_ifip=(172.20.0.3/24 192.168.168.1/24 192.168.195.1/24 192.168.199.1/24)

for arr in ${current_ifip[@]}; do
 if [[ ${state_ip[$arr]} ]]; then
  echo "$arr есть на интерфейсе"
 else
  echo "$arr нет на интерфейсе"
 fi
done
А он вываливается с такой ошибкой
syntax error: invalid arithmetic operator (error token is ".20.0.3/24")
Хочет произвести арифметику. Хотя я по-разному пробовал экранировать и брать в кавычки $arr. Подскажите как правильно выполнить сверку?


Ответ на: комментарий от fet4

Это из-за противоестественного интеллекта такое, если цифры - значить индекс, а не ассоциация. Добавьте везде букву при заполнении и сравнениях.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Жесть, а нет может ключа какого? что бы указал что здесь строка арифметика не нужна.

fet4 ()
state_ip=['172.20.0.3/24', '192.168.168.1/24', '192.168.195.1/24', '192.168.199.1/24']
current_ifip=['172.20.0.3/24', '192.168.168.1/24', '192.168.195.1/24', '192.168.199.1/24']

for ip in current_ifip:
    if ip in state_ip:
        print('yes')
    else:
        print('no')

P.S. python.

conformist ★★★ ()
Последнее исправление: conformist (всего исправлений: 1)
Ответ на: комментарий от fet4

Нате. Специально добавил несуществующий в конец current_ifip

#!/bin/bash

state_ip=(172.20.0.3/24 192.168.168.1/24 192.168.195.1/24 192.168.199.1/24)
current_ifip=(172.20.0.3/24 192.168.168.1/24 192.168.195.1/24 192.168.199.1/24 192.168.199.2/24)

declare -A state_ip_a
declare -A current_ifip_a

i=0
for arr in ${state_ip[@]}; do
 state_ip_a[$arr]=${state_ip[i++]}
done

i=0
for arr in ${current_ifip[@]}; do
 current_ifip_a[$arr]=${current_ifip[i++]}
done

for arr in ${current_ifip_a[@]}; do
 if [[ ${state_ip_a[$arr]} ]]; then
   echo "$arr есть на интерфейсе"
 else
   echo "$arr нет на интерфейсе"
 fi
done

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

На bash'e любой !Ъ сможет, даешь POSIX shell!

#!/bin/sh

normalize() {
	local val="$1"

	local t=${val//\//_}
	echo ${t//./_}
}

load() {
	local prefix="$1"
	local vector="$2"

	set -- $(normalize "${vector}")
	for ip; do
		eval "${prefix}_${ip}=y"
	done
}

########
# Main #
########

state_ip="172.20.0.3/24 192.168.168.1/24 192.168.195.1/24 192.168.199.1/24 192.168.199.133/32"
current_ifip="172.20.0.3/24 192.168.168.1/24 192.168.195.1/24 192.168.199.1/24 192.168.199.2/24"

load "curr_ip" "$current_ifip"

for ip in $state_ip; do
	n=$(normalize "$ip")
	eval val="\$curr_ip_${n}"

	if [ "$val" = y ]; then
		echo "$ip: found"
	else
		echo "$ip: not found"
	fi
done

joy4eg ★★★★★ ()

state_ip это не ассоциативный массив вообще-то, не смущает?

d_a ★★★★★ ()
Ответ на: комментарий от joy4eg

У вас тоже не bourne :) Все эти $(cmd) ${p//}... Если уж юзаете set --, то накой вообще этот load()? Делайте IFS=" " set --. Ну и т д.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

$(cmd)

Это таки POSIX.

${p//}

А это башизм, да :)

Если уж юзаете set --, то накой вообще этот load()?

Чисто эстетически смотрится лучше, ИМХО. Сам смысл load() что бы построить подобие хеш-таблицы.

Делайте IFS=" " set --.

Этого не понял. Зачем IFS менять в данном случае ? ...

joy4eg ★★★★★ ()
Ответ на: комментарий от joy4eg

$(cmd)

Это таки POSIX.

Да это чисто новомодный эфемизм к обратным апострофам, мож и POSIX, но не такой уж и древний.

Зачем IFS менять в данном случае ?

Для гарантии. Это правильный стиль, ибо меняет не глобально и самодокументированно для демонстрации чего хотят сделать в этой строчке.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Это правильный стиль, ибо меняет не глобально и самодокументированно для демонстрации чего хотят сделать в этой строчке.

Я понимаю, что он делает, и для чего нужен в целом. Я спрашивал за другое - чем или как именно замена IFS поможет конкретно в этом случае ? ...

joy4eg ★★★★★ ()
Ответ на: комментарий от joy4eg

чем или как именно замена IFS поможет конкретно в этом случае

Сделает ровно то что вы делаете load() - распарсит строку по аргументам с разделителем пробел.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Почти то что нужно, но не совсем. Помогите доработать.

 for i in vlan8 vlan10; do
  current_if_ip=${i}_ip
  state_ip=$(ip addr show dev $i | grep -w inet | awk '{print $2}')
  current_ifip=(${!current_if_ip})

  unset state_ip_a
  unset current_ifip_a

  declare -A state_ip_a
  declare -A current_ifip_a

  echo ${state_ip[@]}
  echo ${current_ifip[@]}

  h=0
  for arr in ${state_ip[@]}; do
   state_ip_a[$arr]=${state_ip[h++]}
  done

  h=0
  for arr in ${current_ifip[@]}; do
   current_ifip_a[$arr]=${current_ifip[h++]}
  done

  for arr in ${current_ifip_a[@]}; do
   if [[ ${state_ip_a[$arr]} ]]; then
    echo "IPv4-адрес $arr уже добавлен на $i"
   else
    echo "Добавляю IPv4-адрес $arr на $i"
    ip addr add $arr dev $i
   fi
  done

 done;

Первый раз ip добавляются второй раз прогоняю скрипт он снова пытается добавить. Т.е. не отрабатывает проверка в списке.

1-раз


172.20.0.3/24 192.168.168.1/24 192.168.195.1/24 192.168.199.1/24
Добавляю IPv4-адрес 192.168.195.1/24 на vlan8
Добавляю IPv4-адрес 192.168.199.1/24 на vlan8
Добавляю IPv4-адрес 172.20.0.3/24 на vlan8
Добавляю IPv4-адрес 192.168.168.1/24 на vlan8

172.19.0.4/24
Добавляю IPv4-адрес 172.19.0.4/24 на vlan10

2-раз

192.168.195.1/24 192.168.199.1/24 172.20.0.3/24 192.168.168.1/24
172.20.0.3/24 192.168.168.1/24 192.168.195.1/24 192.168.199.1/24
IPv4-адрес 192.168.195.1/24 уже добавлен на vlan8
Добавляю IPv4-адрес 192.168.199.1/24 на vlan8
RTNETLINK answers: File exists
Добавляю IPv4-адрес 172.20.0.3/24 на vlan8
RTNETLINK answers: File exists
Добавляю IPv4-адрес 192.168.168.1/24 на vlan8
RTNETLINK answers: File exists
172.19.0.4/24
172.19.0.4/24
IPv4-адрес 172.19.0.4/24 уже добавлен на vlan10

fet4 ()
#/usr/bin/perl -CS -Mutf8
@state_ip = qw! 172.20.0.3/24 192.168.168.1/24 192.168.195.1/24 192.168.199.1/24 !;
@current_ifip = qw! 172.20.0.3/24 192.168.168.1/24 192.168.195.1/24 192.168.199.1/24 10.1.1.17/8 !;
@{$sti = {}}{@state_ip} = @state_ip;
map { print "$_ ".($sti->{$_}?"есть":"нету")." на интерфейсе\n" } @current_ifip;
berrywizard ★★★★★ ()
Ответ на: комментарий от fet4

state_ip=$(ip addr show dev $i | grep -w inet | awk '{print $2}')

Это строка

Напишите так:

state_ip=($(ip addr show dev eth1 | grep -w inet | awk '{print $2}'))

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Блин точно! Работает как нужно. А почему нельзя сразу добавить в ассоциативный массив ip? Спасибо за помощь!

fet4 ()
Ответ на: комментарий от fet4

Ассоциативный массив current_ifip вообще не нужен, это было чисто для демонстрации, а добавлять в ассоциативный массив можно только один способом - создать ассоциацию ключ-значение.

vodz ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.