Debian - как запустить скрипт при запуске, как только интернет-соединение готово к использованию?


14

Я использую Debian 7 Wheezy, и мне нужно запустить несколько экранов при запуске, как только появится полностью функциональное подключение к Интернету. Однако, нет, если интернет-соединение оборвалось и было снова подключено. Так что только по первому функциональному интернет подключению после загрузки.

Не могли бы вы опубликовать фиктивный сценарий для этого и сказать мне, где его поставить и чтобы он выполнялся в данных условиях?

Сценарий должен только запустить экран и затем завершиться, но экран должен продолжаться.


РЕДАКТИРОВАТЬ Я уже слышал о /etc/network/if-up.d/папке. Но как я могу убедиться, что скрипт не будет выполнен снова, если интернет-соединение потеряно, а затем восстановлено?


@Celada, пожалуйста, смотрите правку
MinecraftShamrock

Ответы:


21

Вставьте ваш скрипт /etc/network/if-up.dи сделайте его исполняемым. Он будет автоматически запускаться каждый раз, когда появляется сетевой интерфейс.

Чтобы он работал только при первом запуске при каждой загрузке, попросите его проверить наличие файла флага, который вы создаете после первого раза. Пример:

#!/bin/sh

FLAGFILE=/var/run/work-was-already-done

case "$IFACE" in
    lo)
        # The loopback interface does not count.
        # only run when some other interface comes up
        exit 0
        ;;
    *)
        ;;
esac

if [ -e $FLAGFILE ]; then
    exit 0
else
    touch $FLAGFILE
fi

: here, do the real work.

Будет ли удален флаг-файл при завершении работы сервера?
MinecraftShamrock

1
Да, потому что в Debian /var/runесть нестабильная файловая система (а tmpfs). Так что он гарантированно будет пустым при каждой новой загрузке.
Celada

1
Хороший улов. Я думаю, вам должно быть не повезло, но я думаю, что да, из-за горячих подключаемых интерфейсов, которые могут быть запущены одновременно. Так что я думаю, что вы можете сделать это атомарно вместо test-then-create, что сделало бы это безопасным, но то, что я придумал, не очень красиво! python -c 'import os; os.open("/var/run/work-was-already-done", os.O_EXCL|os.O_CREAT, 0)' 2>/dev/null || exit 0
Селада

3
@MinecraftShamrock Если вы используете скрипт Celada как есть, ваш код будет запущен, как только появится интерфейс обратной связи. Если вы хотите подождать подключения к Интернету, по крайней мере, проверьте, что IFACEнет lo- или какой-то виртуальный интерфейс - или лучше, проверьте подключение к Интернету с помощью ping
Жиль "ТАК ... перестать быть злым"

1
@MinecraftShamrock $IFACEможет иметь в качестве значений любой интерфейс, который подходит. Вы можете перечислить все интерфейсы, которые существуют, ip linkили посмотреть, какие из них настроены для сканирования при сканировании/etc/network/interfaces
Celada

9

Эта работа очень хорошо подходит для systemd.

Запуск сценария как службы systemd

Если ваша система работает под управлением systemd , вы можете настроить скрипт для запуска в качестве службы systemd, которая обеспечивает контроль над жизненным циклом и средой выполнения, а также предварительные условия для запуска скрипта, такие как работоспособность и работоспособность сети.

Рекомендуемая папка для ваших собственных сервисов /etc/systemd/system/(другой вариант, /lib/systemd/systemно обычно его следует использовать только для сервисов OOTB).

Создайте файл, например, с помощью sudo vim /etc/systemd/system/autossh.service:

[Unit]
# By default 'simple' is used, see also https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=
# Type=simple|forking|oneshot|dbus|notify|idle
Description=Autossh keepalive daemon
## make sure we only start the service after network is up
Wants=network-online.target
After=network.target

[Service]
## here we can set custom environment variables
Environment=AUTOSSH_GATETIME=0
Environment=AUTOSSH_PORT=0
ExecStart=/usr/local/bin/ssh-keep-alive.sh
ExecStop=pkill -9 autossh
# don't use 'nobody' if your script needs to access user files
# (if User is not set the service will run as root)
#User=nobody

# Useful during debugging; remove it once the service is working
StandardOutput=console

[Install]
WantedBy=multi-user.target

Теперь вы можете протестировать сервис:

sudo systemctl start autossh

Проверка статуса услуги:

systemctl status autossh

Остановка сервиса:

sudo systemctl stop autossh

После того, как вы убедились, что сервис работает должным образом, включите его:

sudo systemctl enable autossh

ПРИМЕЧАНИЕ. В целях безопасности systemdсценарий будет запускаться в ограниченной среде, аналогично тому, как crontabвыполняются сценарии, поэтому не делайте предположений о ранее существующих системных переменных, таких как $ PATH. Используйте Environmentключи, если ваш сценарий требует определенных переменных, которые будут определены. Добавление set -xи запуск в верхней части скрипта bash systemctl status my_serviceможет помочь определить причину сбоя скрипта. Как правило, всегда используйте абсолютные пути для всего, включая echoили явно определяйте свой $ PATH, добавляя Environment=MYVAR=abc.


2

Подключение к интернету вызвано записью в /etc/rc6.d/вероятно S35networking. Если вы изменяете этот файл и вставляете свои команды в конце, или лучше добавляете /etc/init.d/mystuffссылку и ссылку /etc/rc0.d/S36mystuffна него и вставляете туда свои команды, то это начнется, как только сеть начнет работать.


Будет ли он вызываться, если соединение потеряно, а затем восстановлено? Потому что в противном случае я мог бы просто вставить сценарий в/etc/network/if-up.d
MinecraftShamrock

Нет, это только при запуске
Anthon

1
Это будет работать, но просто для правильности позвольте мне указать, что ни один скрипт /etc/rc0.dне будет запущен при запуске, он будет работать при завершении работы (уровень запуска 0). При запуске это будет что-то /etc/rc2.dпохожее. Специально для Debian Wheezy OP, это /etc/rcS.d/S12networking. Конечно, все это ссылки на один и тот же файл. Кроме того, кстати, Антон, спасибо, что исправили мой ответ: «Пожалуйста» вместо «Поставить»? Какая странная опечатка!
Celada

@Celada Вы правы, это rc6 в моей системе (не Debian). Я не был уверен, хотите ли вы «Пожалуйста, положите» туда, но просто «Положить» показалось более хрустящим. Кстати, я проголосовал за ваш ответ, это просто лучший подход для работы в сети, поскольку он имеет if-up.dобщий механизм, который также работает на повторное подключение.
Антон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.