Как добавить и добавить к каждому элементу массива?

Socat OpenWRT

Socat уже был указан в качестве ответа, однако указанный ответ не работал для меня на моей платформе, OpenWRT, с динамическим WAN-адресом.

Моя цель заключается в пересылке одноадресных UDP пакетов wake-on-lan с UDP порта 9 WAN интерфейса на подсеть, транслируемую на 192.168.20.255.

Сломанный (iptables)

Я тоже пытался использовать iptables, но каждый раз, когда я добавляю правило, которое заканчивается на 255, правило превращается в mush с адресом назначения 0.0.0.0, когда я печатаю с:

iptables -t nat -L

Я считаю, что iptables не способен мультиплексировать трафик, как это требуется при преобразовании одноадресной рассылки в широковещательную.

Плохое (подделка записей arp)

Подделка записей arp не так уж плоха, потому что пакеты попадают ко всем в сегменте ethernet, но у нее есть следующие недостатки

  • Вы "потребляете" IP-адрес
  • IP-адрес назначения в пакете WoL неверен, хотя вы получаете его, потому что MAC-адрес все FFFF...
  • Сбой IP может произойти, если кто-то в сети использует этот IP-адрес.
  • Это широковещательная передача Ethernet, а не IP-рассылка.

Примечание: Это может быть сделано с помощью команды arp или ip neigh.

Хороший

socat, как следует из предыдущего ответа, - это badass. Предыдущий ответ socat, однако, я столкнулся с несколькими проблемами с ним.

  1. Мой socat не пересылал трафик, когда широковещательное назначение UDP было 255.255.255.255. Я избежал этого, ограничив широковещательную подсеть до той, которую я использую, что, вероятно, более безопасно.
  2. Когда я установил адрес привязки 0.0.0.0, я столкнулся с широковещательным штормом из-за трафика, возвращающегося в socat из моей локальной сети. Сначала я решил эту проблему привязкой к публичному ddns, однако это не идеальный вариант, поскольку ddns может быть недоступен, а мой динамически назначаемый IP-адрес может измениться.

Я смог привязаться к 0.0.0.0 (все адреса) и избежать широковещательного шторма, добавив правило iptables для блокирования входящего широковещания, чтобы оно не возвращалось в socat со стороны LAN. Это правило, в дополнение к правилу iptables для приема трафика на UDP порт 9, и правилу iptables для его регистрации, мы получаем следующие три правила в дополнение к команде socat.

iptables -I input_wan_rule -p udp --dport 9 -j ACCEPT -m comment --comment "firewall entry to allow udp port 9 to socat"
iptables -I input_wan_rule -p udp --dport 9 -j LOG --log-prefix 'Received MAGIC PACKET on udp/9'
iptables -I input_lan_rule -p udp --dport 9 -d 192.168.20.0/24 -j DROP -m comment --comment "block broadcast from bouncing back to socat to avoid storm"

killall socat 2>/dev/null
socat -u -T1 UDP-LISTEN:9,bind=0.0.0.0,fork UDP-DATAGRAM:192.168.20.255:9,broadcast &

Для пользователей OpenWRT достаточно вставить это в /etc/firewall.user и выполнить /etc/init.d/firewall restart.

Поздравляем, теперь WoL должен работать в вашей сети из любой точки Интернета.

7
24.05.2015, 00:40
1 ответ

Aquí hay una solución de caso especial que es adecuada cuando la cadena adjunta (o antepuesta )es un carácter único , y no necesita los valores en un nueva matriz:

array=( aa bb cc )
IFS="]"                        # or, IFS="["
echo "${array[*]/#/ [}$IFS"    # or, echo "$IFS${array[*]/%/] }

que produce la salida [aa] [bb] [cc].

  • forma citada "${array[*]}"agrega separador ]entre cada par (el primer carácter de IFS, aquí es donde surgen las restricciones)
  • ${array[*]/#/ [}antepone[a cada elemento (o /%/formulario para agregar)
  • finalmente agregue un final](desdeIFS)al valor expandido

Si se aplican estos pasos uno por uno se obtendría:

aa]bb]cc
 [aa] [bb] [cc
 [aa] [bb] [cc]

(También podría recuperar trivialmente los datos como una nueva matriz si los valores no contienen espacios en blanco.)

Puede hacer las distintas operaciones de prefijo/postfijo en una -línea:

for ii in "${array[@]/#/foo }"; do echo "${ii/%/ bar}"; done

Esta es una solución más robusta printfque copia a una nueva matriz:

mapfile -d '' newarray < <(printf "foo %s bar\0" "${array[@]}")

aunque a expensas de un subshell (bash -4.4 requerido paramapfile -d)

Finalmente, una variación de bucle que copia a una nueva matriz y también maneja matrices dispersas y asociativas, si es necesario.

declare -a array newarray   # -a for indexed array, -A for associative
array=( one two three )
for ii in "${!array[@]}"; do
  printf -v "newarray[$ii]" "foo %s bar" "${array[$ii]}"
done

(printfno es obligatorio, puede asignarlo directamente,pero es más claro en mi humilde opinión. ¡bashtodavía no (! )admite la impresión en una matriz, pero zshlo hace, lo que le brinda una copia sin bucles y transforma una línea -, consulte la respuesta de Stéphane anterior.)


Lo que sería útil aquí es si bashadmitiera el común&(como $MATCHenzsh)como un marcador de lugar -para la cadena coincidente en expansiones. El código está allí(y lo ha estado durante mucho tiempo ), pero lamentablemente aún no está habilitado (consulte shouldexp_replacement()ensubst.c). Si lo habilita (dos #if 0cambios y vuelve a compilar ), esto funciona como se esperaba:

array=( aa bb cc )
newarray=( "${array[@]/*/foo & bar}" )

No importa, quizás disponible en la próxima versión...

compgentiene una operación de prefijo/sufijo (y admite &, pero no de una manera que podamos usar aquí ). Lo mejor que podemos hacer con él no es tan buena solución de muru printf:

compgen -P "foo " -S " bar" -W "${array[*]}"

(nota -Wtoma solo una opción, por lo que la matriz se aplana, y esto causa problemas con valores con espacios o cualquier cosa enIFS)

1
27.01.2020, 20:14

Теги

Похожие вопросы