Почему printf «сжимает» умлаут? имеет несколько правильных решений, вызывая соответствующие инструменты для этого, поскольку bash
пропускает эту возможность внутри, или переключаясь на другие оболочки, но если вы действительно хотите реализовать это в bash
только со встроенными командами, есть способы для одного -ширины (потенциально нескольких -байтов )символов.
В bash, как и во всех оболочках POSIX, вы можете получить ширину в символах $string
с помощью ${#string}
и ${#string}
, но в локали C для ширины в байтах.
Таким образом, вы можете объяснить несоответствие чем-то вроде:
clength() { clength=${#1}; }
blength() { local LC_ALL=C; blength=${#1}; }
align() {
local format="$1" width="$2" arg blength clength
shift 2
for arg do
clength "$arg"; blength "$arg"
printf "$format" "$((width + blength - clength))" "$arg"
done
}
a=(0 00 000 0000 00000)
b=(0 ├─00 ├─000 ├─0000 └─00000)
align '%-*s|\n' 12 "${a[@]}" "${b[@]}"
Для учета нулевой -ширины (, такой как объединение меток )или символов двойной ширины -, нет решения с bash
, только если вы не готовы жестко закодировать список таких символов. в вашем скрипте (или используйте escape-последовательности терминала, чтобы указать терминалу выровнять текст (последний пример там или там)и жестко закодировать escape-последовательности для всех поддерживаемых терминалов поскольку bash
также не имеет встроенного интерфейса для terminfo/termcap ). zsh и ksh93 — единственные известные мне оболочки со встроенной поддержкой выравнивания символов переменной ширины дисплея (, пример также в связанных вопросах и ответах).
Хорошо, теперь я это сделал. Позвольте мне провести вас через процесс настройки. Моя конфигурация частично выдерживает перезагрузки.
Во-первых, я проверил это с 2 B4, 1 AFTR и всеми системами, настроенными вручную.
Также я предполагаю, что ваш AFTR имеет адрес IPv6 2000::1
, первый B4 имеет адрес 2000::2
, а второй имеет адрес 2000::3
. Интерфейс WAN AFTR имеет здесь имя eth0
.
Давайте приступим к делу.
Сначала я создал туннели на AFTR и B4 вручную.
На AFTR:
root@AFTR:~# ip tunnel add dslite mode ip4ip6 local 2000::1 remote 2000::2
root@AFTR:~# ip tunnel add dslite2 mode ip4ip6 local 2000::1 remote 2000::3
root@AFTR:~# ip link set dslite up; ip link set dslite2 up
root@AFTR:~# ip a add 192.0.0.1/29 dev dslite; ip a add 192.0.0.1/29 dev dslite2
Теперь мы уже можем установить туннели на B4. На B4 1:
root@B4-1:~# ip link set dslite up
root@B4-1:~# ip a add 192.0.0.2/29 dev dslite
root@B4-1:~# ip route add default via 192.0.0.1 dev dslite
На B4 2:
root@B4-2:~# ip link set dslite up
root@B4-2:~# ip a add 192.0.0.2/29 dev dslite
root@B4-2:~# ip route add default via 192.0.0.1 dev dslite
Теперь туннели настроены и запущены. Но NAT еще не реализован на AFTR.
root@AFTR:~# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE (eth0 is the Internet side network card)
root@AFTR:~# echo "1 dslite" >> /etc/iproute2/rt_tables
root@AFTR:~# ip route add default dev dslite table dslite
root@AFTR:~# iptables -t mangle -A PREROUTING -i dslite -j MARK --set-mark 1
root@AFTR:~# iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark
root@AFTR:~# iptables -t mangle -I PREROUTING -j CONNMARK --restore-mark
root@AFTR:~# ip rule add fwmark 1 iif eth0 table dslite
root@AFTR:~# echo "2 dslite2" >> /etc/iproute2/rt_tables
root@AFTR:~# ip route add default dev dslite2 table dslite2
root@AFTR:~# iptables -t mangle -A PREROUTING -i dslite2 -j MARK --set-mark 2
root@AFTR:~# ip rule add fwmark 2 iif eth0 table dslite2
root@AFTR:~# sysctl -w net.ipv4.fwmark_reflect=1
Теперь B4 должны иметь доступ к IPv4 (и, конечно, IPv6 )Интернету. Но это не значит, что они могут достигать друг друга, не забывайте об этом, экспериментируя.
Наконец-то решено...