В общем, ifup
/ ifdown
не гарантирует, что ваш скрипт запускается только один раз. Таким образом, ваш сценарий должен быть идемпотентом; то есть содержать свою собственную логику, чтобы не создавать туннель, который уже существует. Конечно, лучший способ - запустить скрипт, фактически проверив, существует ли туннель:
# Exit if network device "tun0" exists.
ip link show dev tun0 >/dev/null 2>&1 && exit 0
Кроме того, скрипты в if-up.d
и т.д. Запускаются для каждого вызываемого интерфейса.
Как правильно заметил Джефф, сценарии if-*.d
не получают аргументов, указывающих, например, какой интерфейс подходит.
Вместо этого, в соответствии со страницей руководства interfaces(5) :
There exists for each of the above mentioned options a directory
/etc/network/if-<option>.d/ [...]
All of these commands have access to the following environment vari‐
ables.
IFACE physical name of the interface being processed
LOGICAL
logical name of the interface being processed
[... and more ...]
Решение состоит в том, чтобы запустить скрипт с проверкой правильного значения IFACE
, например:
# Exit if we're not starting "eth0".
[ "$IFACE" = 'eth0' ] || exit 0
В противном случае сценарий будет выполняться для каждого сетевого устройства, включая lo
, и в этот момент может быть слишком рано устанавливать туннель.