Спасибо за интересный вопрос. Я хотел бы сделать то же самое в своих сценариях. Документация объемна и не так проста для понимания; Я пока не научился работать без реальных опций в скрипте. Вот моя первая попытка достичь цели с реальными вариантами.
Сначала я создал сценарий оболочки с именем myscript.sh
, который использует параметры.
#!/usr/bin/env sh
self=$(basename "$0")
hflag=0 # Boolean: hflag is not yet detected
dflag=0 # Boolean: dflag is not yet detected
function usage() {
echo "Usage: $self [ -h | -d ]"
}
# If no options were given, exit with message and code.
if (($# == 0)); then
usage
exit 1
fi
# Process options and option arguments.
while getopts ":h:d:" option; do
case "${option}" in
h ) hflag=1 # The h option was used.
host=${OPTARG} # The argument to the h option.
;;
d ) dflag=1 # The d option was used.
dir=${OPTARG} # The argument to the d option.
;;
\?) # An invalid option was detected.
usage
exit 1
;;
: ) # An option was given without an option argument.
echo "Invalid option: $OPTARG requires an argument" 1>&2
exit 1
;;
esac
done
# One of hflag or dflag was missing.
if [ $hflag -eq 0 ] || [ $dflag -eq 0 ]; then
usage
exit 1
fi
# Do something with $host and $dir.
# This is where the actions of your current script should be placed.
# Here, I am just printing them.
echo "$host"
echo "$dir"
# Unset variables used in the script.
unset self
unset hflag
unset dflag
Затем я определил, где zsh
искать файлы автозаполнения.
print -rl -- $fpath
Я выбрал один из каталогов, /usr/local/share/zsh/site-functions
в моем случае. Имена файлов, которые считаются файлами автозаполнения, начинаются с символа подчеркивания _. Я создал файл _myscript
в каталоге. Часть после #compdef
— это фактическое имя скрипта выше.
#compdef myscript.sh
_myscript() {
_arguments '-h[host]:hosts:_hosts' '-d[directory]:directories:_directories'
}
_myscript "$@"
Затем я выполнил compinit
, чтобы получить новое определение автозаполнения, предоставленное файлом _myscript
. В результате теперь я могу использовать завершение с помощью табуляции для указания хоста после опции -h
и каталога после опции -d
, сохраняя при этом некоторое здравомыслие при анализе опций и аргументов опций в самом скрипте. Завершение табуляции представляет доступные параметры еще до вызова myscript.sh
, а также делает порядок параметров неактуальным.
Использование становится примерно следующим.
myscript.sh -h -d ~/test/
Со второй попытки я создал простой сценарий оболочки, zscript.sh
.
#!/usr/bin/env sh
echo "$1"
echo "$2"
И я создал файл, /usr/local/share/zsh/site-functions/_zscript
.
#compdef zscript.sh
_zscript() {
_arguments '1: :->hostname' '2: :->directory'
case $state in
hostname)
_hosts
;;
directory)
_directories -W $HOME/test/
;;
esac
}
Я казнил compinit
.
Вот схема Поток пакетов в Netfilter и General Networking :
В то время как входящий пакет был помечен в PREROUTING, локально сгенерированный ответный пакет действительно вышел через OUTPUT :, нет правила для его маркировки, поэтому нет метки и маршрут другой.
Изменение пакета в mangle/OUTPUT, включая изменение метаинформации -, такой как метка, запускает проверку перенаправления. Это перенаправление должно переключить маршрут с eth0 на ge -0.0.0 -Iosv6(note :с nftables вместо iptables , для этого )требуется выделенный тип цепи маршрута . Это правило сделает это:
iptables -t mangle -A OUTPUT -s 6.6.6.6 -j MARK --set-mark 1
Вместо того чтобы помечать независимые пакеты определенными правилами обоими способами, можно автоматически пометить весь поток (как отслеживаемый conntrack). Можно использовать соответствиеconnmarkи его целевой аналогCONNMARK . В этом блоге приведены примеры использования:Netfilter Connmark .
В этом случае вместо правила iptables выше:
должно быть последним правилом в mangle/PREROUTING:
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j CONNMARK --save-mark
должно быть первым правилом в mangle/OUTPUT, чтобы его можно было изменить при необходимости.Это вызовет проверку перенаправления :
.iptables -t mangle -I OUTPUT -m connmark ! --mark 0 -j CONNMARK --restore-mark
Есть также несколько вещей, которые нужно знать, и предостережения, которые довольно трудно надежно предсказать без тестирования:
Переключениеfwmark_reflect
(например,:sysctl -w net.ipv4.fwmark_reflect=1
)могло бы быть достаточным для этого конкретного случая и использоваться вместо правил выше, но не помогло бы в более общем случае. Точно так же естьtcp_fwmark_accept
для облегчения случая TCP. Для других протоколов, таких как UDP, нет эквивалента.
иногда маршрут терпит неудачу до проверки перенаправления из-за строгой переадресации обратного пути , и пакет отбрасывается раньше, чем он получает возможность быть помеченным и перенаправленным. Очевидно, что здесь это не так (SRPF может быть даже не включен ), но если это произойдет, следует слишком ослабить проверку на одном из задействованных интерфейсов (тесты, необходимые для определения того, какой ), изменивrp_filter
настройки (, например :sysctl -w net.ipv4.conf.eth0.rp_filter=2
).
Иногда некоторые дополнительные маршруты из основной таблицы должны быть продублированы в дополнительной таблице, так как они сначала считываются, прежде чем вернуться в основную таблицу и могут не совпадать. Трудно понять, когда это необходимо, особенно когда задействованы метки . Например:
ip route add table threehundred 192.168.100.2/32 dev ge-0.0.0-Iosv6
команда ip route get...
, даже если она снабжена адекватным mark
, по-видимому, не всегда точно предсказывает, что происходит в настоящее время, когда задействованы метки и iptables .
поведение, связанное с взаимодействием между меткой, маршрутом и, возможно, ip route get
предсказанием, можно изменить с помощью недокументированногоsrc_valid_mark
переключателя (также черезsysctl
). Используйте его, только если кажется, что он исправляет ситуацию.
Поведение UDP-сервера в случае маршрутизации на основе политик может отличаться от поведения TCP-сервера по сложным для объяснения причинам.Использование меток может только увеличить сложность.