Существует ли в systemd аналог функции runonce?

Мне нужен сервис, аналогичный oneshot, который будет выполняться только один раз после перезагрузки и не будет запускаться после последующих перезагрузок. Правильно ли я понимаю, что в Windows для этого используется ветка реестра RunOnce? 

Также, я могу добавить команду `sudo systemd --disable unit` в скрипт, вызываемый юнитом, но это кажется не совсем удобным решением.
  • 6 декабря 2024 г. 15:03
Ответы на вопрос 2
В `systemd` нет прямого аналога функции `RunOnce` из Windows, однако вы можете использовать некоторые трюки для достижения аналогичного результата.

Ваше предложение относительно использования типа юнита `oneshot` — это правильный подход, но вам действительно нужно убедиться, что он не будет выполняться повторно после первой загрузки. Хотя идея использовать команду `systemctl disable` в самом юните работает, это может быть не самым элегантным решением.

Вот другие методы, которые вы можете рассмотреть:

### 1. Использование файла-сигнала

Вы можете сделать юнит-скрипт `oneshot`, который будет проверять наличие файла-сигнала (например, `/var/tmp/my_runonce_complete`). Если файл существует, юнит просто завершится, не выполняя основное действие. Если файла нет, ваш скрипт выполнит необходимую задачу и создаст файл:

```ini
[Unit]
Description=My RunOnce Service

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'if [ ! -f /var/tmp/my_runonce_complete ]; then
    # Ваши команды здесь
    touch /var/tmp/my_runonce_complete;
fi'

[Install]
WantedBy=multi-user.target
```

### 2. Использование `tmpfiles.d`

Вы также можете зарегистрировать файл в `tmpfiles.d` для создания и удаления файла-сигнала, если это удобно. Это обеспечит исполнение только один раз при загрузке системы.

### 3. Выполнение через `systemd` timer

Если вам необходимо более сложное управление выполнением, вы также можете использовать комбинацию юнитов типа `oneshot` и `timer`, чтобы управлять частотой и условиями запуска.

### 4. Ручное удаление юнита после первого запуска

Если ваш скрипт выполняет некоторую проверку состояния системы и требует выполнения только один раз, можно также создать юнит, который будет автоматически удаляться после первого выполнения. Для этого вам нужно будет в скрипте вызвать команду `systemctl disable` и/или `systemctl stop` для завершения юнита после выполнения.

## Заключение

Из вышеописанных методов наиболее популярным и простым является использование файла-сигнала. Попробуйте его реализовать, это не требует изменений в конфигурациях системы, и его можно легко адаптировать под ваши нужды.
вполне нормально :) в системд не делали отдельной внутренней опции выключения юнитов. 
Type=oneshot
ExecStopPost=/usr/bin/systemctl --disable %N
Похожие вопросы