Доступ к файлу через символическую ссылку эквивалентен замене базового имени файла текстом символической ссылки, если текст символической ссылки не начинается с/
(относительной ссылки ), и заменой полного пути к файлу символической ссылкой текст, если символическая ссылка начинается с/
(абсолютная ссылка ). Если в тексте символической ссылки есть завершающая косая черта, пусть будет так.
Косая черта в конце имени файла означает, что «файл должен быть каталогом». Если целью ссылки является каталог, то доступ к файлу в нем приводит к вычисляемому пути, который содержит две косые черты :, одну из текста символической ссылки, а другую в качестве разделителя каталогов. Учитывая
lrwxr-xr-x 1 user wheel 15B 2 Aug 08:36 test-notail -> /ln-test/FOLDER
lrwxr-xr-x 1 user wheel 16B 2 Aug 08:36 test-tail -> /ln-test/FOLDER/
, тогда test-notail/foo
эквивалентно /ln-test/FOLDER/foo
и test-tail/foo
эквивалентно /ln-test/FOLDER//foo
.
Несколько косых черт равны одной(за одним исключением :путь, начинающийся ровно с двух косых черт, в некоторых системах ).Таким образом, завершающая косая черта (или несколько завершающих косых черт )в символической ссылке на каталог не имеют значения для системы.
Если дополнительная косая черта влияет на приложение, это ошибка в приложении.
Обратите внимание, что в приведенных ниже объяснениях модуль означает пользовательскую команду iptables модуль, а не модуль ядра (Конечно, связь есть, но в объяснении она не нужна ).
iptables
касается IPv4. Каждый пакет IPv4 имеет поле протокола . --protocol tcp
использует встроенный -в код iptables для сравнения с заданным значением. Базовая команда iptables сама по себе мало что знает о базовом уровне IPv4. Если больше ничего не требуется, например проверка определенного TCP-порта, iptables не идет дальше. Например:
iptables -A INPUT -p tcp -j ACCEPT
не будет загружать модуль tcp . И не будет никаких -m tcp
увиденных позже.
Базовая команда iptables не знает о порте. Когда неизвестная опция указана после тестирования протокола, в качестве любезности iptables автоматически загружает модуль с именем протокола, это роль опции -m
. Таким образом, под капотом iptables -A INPUT -p tcp --dport 5555
, не найдя опции --dport
, автоматически вставляется -m tcp
. Теперь опция --dport
снова проверяется на соответствие модулю tcp , и этот модуль знает об опции --dport
и обрабатывает ее. Вот почему, когда вы делаете:
iptables -A INPUT -p tcp --dport 5555
и сбрасывает правила с помощью iptables-save
вы увидите в результате это вместо:
-A INPUT -p tcp -m tcp --dport 5555
Обычно люди не набирают -m tcp
, а копируют любые результаты из дампа правил, потому что это проще и означает, что в команде не будет синтаксической ошибки.
Если вы хотите убедиться в этом, вот что происходит в этих strace примерах, когда вы задаете или не задаете опцию --dport
после указания опции -p icmp
для протокола ICMP (который не имеет концепции порта):
# strace iptables -A INPUT -p icmp 2>&1 |egrep 'icmp|write'
execve("/usr/sbin/iptables", ["iptables", "-A", "INPUT", "-p", "icmp"], [/* 15 vars */]) = 0
и
# strace iptables -A INPUT -p icmp --dport 5555 2>&1 |egrep 'icmp|write'
execve("/usr/sbin/iptables", ["iptables", "-A", "INPUT", "-p", "icmp", "--dport", "5555"], [/* 15 vars */]) = 0
stat("/usr/lib/x86_64-linux-gnu/xtables/libipt_icmp.so", {st_mode=S_IFREG|0644, st_size=14464,...}) = 0
open("/usr/lib/x86_64-linux-gnu/xtables/libipt_icmp.so", O_RDONLY|O_CLOEXEC) = 3
getsockopt(3, SOL_IP, IPT_SO_GET_REVISION_MATCH, "icmp\0\177\0\0\207\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!\0\0\0\0\0", [30]) = 0
write(2, "iptables v1.8.3 (legacy): ", 26iptables v1.8.3 (legacy): ) = 26
write(2, "unknown option \"--dport\"", 24unknown option "--dport") = 24
write(2, "\n", 1
write(2, "Try `iptables -h' or 'iptables -"..., 61Try `iptables -h' or 'iptables --help' for more information.
Наличие параметра, неизвестного iptables, вызвало загрузку модуля icmp(файла libipt_icmp.so
), поскольку был указан протокол icmp . Этот модуль также не смог обработать параметр --dport
, поэтому iptables не выполнил эту команду.