Socat уже был указан в качестве ответа, однако указанный ответ не работал для меня на моей платформе, OpenWRT, с динамическим WAN-адресом.
Моя цель заключается в пересылке одноадресных UDP пакетов wake-on-lan с UDP порта 9 WAN интерфейса на подсеть, транслируемую на 192.168.20.255.
Я тоже пытался использовать iptables, но каждый раз, когда я добавляю правило, которое заканчивается на 255, правило превращается в mush с адресом назначения 0.0.0.0, когда я печатаю с:
iptables -t nat -L
Я считаю, что iptables не способен мультиплексировать трафик, как это требуется при преобразовании одноадресной рассылки в широковещательную.
Подделка записей arp не так уж плоха, потому что пакеты попадают ко всем в сегменте ethernet, но у нее есть следующие недостатки
Примечание: Это может быть сделано с помощью команды arp
или ip neigh
.
socat, как следует из предыдущего ответа, - это badass. Предыдущий ответ socat, однако, я столкнулся с несколькими проблемами с ним.
Я смог привязаться к 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 должен работать в вашей сети из любой точки Интернета.
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]
.
"${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)]
(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 printf
que 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
(printf
no es obligatorio, puede asignarlo directamente,pero es más claro en mi humilde opinión. ¡bash
todavía no (! )admite la impresión en una matriz, pero zsh
lo 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 bash
admitiera el común&
(como $MATCH
enzsh
)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 0
cambios 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...
compgen
tiene 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 -W
toma solo una opción, por lo que la matriz se aplana, y esto causa problemas con valores con espacios o cualquier cosa enIFS
)