Скрипт на выключение ubuntu

Обновлено: 04.07.2024

Я хочу, чтоб моя Ubuntu автоматически отключалась каждый день в определенное время. Как этого можно добиться?

1,377 1 1 золотой знак 9 9 серебряных знаков 23 23 бронзовых знака

На помощь нам придет юниксный демон по имени cron .
Для того, чтобы поставить задачу в расписание, мы добавим ее в файл /etc/crontab .
Открываем терминал — Ctrl Alt T .
Файл можно редактировать такой командой:

Для отключения компьютера каждый день в 23:03 добавим в файл такую строчку:

Последняя строчка файла должна быть пустая.

Эта часть была написана по мотивам askubuntu.

Объяснение подробнее.

(Обновлено)

В самом этом файле /etc/crontab объясняется формат таблицы задач:

Первые два поля — минута и час запуска задачи,
3-е поле (dom) — день месяца (Day of Month),
затем месяц,
5-е поле (dow) — день недели,
затем пользователь, от чьего имени будет запускаться команда,
и, собственно, команда.

Время запуска
Все условия (времени запуска) проверяются по «логическому И», кроме условий «день недели» и «день месяца» — указанные совместно, они обрабатываются по «логическому ИЛИ», то есть «по любому из дней», что отражено в документации (Ubuntu, Debian, FreeBSD). (См. Википедия, man 5 crontab ). Если вы хотите проверять их по «логическому И», делайте это в самой команде.

Например, перезагрузка в пятницу, 13-го:

Crontab пользователя.
Кроме общей таблицы crontab, каждый пользователь имеет свою. Свою личную таблицу можно редактировать командой

Таблицу другого пользователя, например, 'root'-а, можно редактировать командой

В первоначальном вопросе правильнее, я думаю, было бы использовать именно этот вариант.
Если в системе есть всего один пользователь, то можно отключать компьютер и через него, и через 'root', без разницы.

Спасибо господам 0andriy и Sergey, который привлекли мое внимание к такой возможности.

Обратите внимание, что в таблице конкретного пользователя формат задачи немного другой, там не нужно указывать пользователя. Вместо

Переменные окружения
Популярная причина проблем с работой crontab -- другое определение переменных окружения при работе демона cron , особенно переменной $PATH .
Вы можете узнать переменные окружения cron -а, вставив в crontab строчку

После того, как файл /tmp/env.output создан, эту строчку можно убрать.
Оказывается, в Ubuntu cron запускается с PATH=/usr/bin:/bin . Для корректной работы нужно определить правильный $PATH в самом файле crontab .
Обратите внимание, что значение переменных не подставляется, то есть

не сработает.
Альтернативный способ решения этой проблемы -- использовать полные пути для запуска команд. Но он хуже, если вы хотите проверить свою команду в терминале или перенести в другую систему.

Если вы запускаете программы с GUI, вам также надо определить $DISPLAY:

Да, и не забывайте в конце crontab -а вставлять пустую строчку.

Вторая часть ответа была написана по мотивам вопроса о проблемах работы с crontab -ом на askubuntu.
Спасибо всем комментаторам за плодотворную дискуссию.

Выключение компьютера - действие, с которым обычные пользователи сталкиваются чуть ли не каждый день. Если выключать сервер приходится довольно редко, то обычные, десктопные компьютеры подвержены этой операции очень даже часто. Большинство пользователей выключают linux в графическом интерфейсе системы. В окружении рабочего стола KDE это делается через главное меню, а в Gnome и Unity даже есть специальная кнопка на панели для решения этой задачи.

Но не всегда есть возможность выключить компьютер linux таким образом. Например, если окружение рабочего стола не работает, то больше ничего не остается, кроме того, чтобы выполнять выключение компьютера из командной строки. К тому же выключение компьютера linux через терминал единственно возможный способ для серверов, где нет графического интерфейса. Как вы увидите, этот способ также намного гибче обычного выключения, поскольку вы можете настроить нужное время отключения, или же выключить компьютер, дождавшись завершения работы определенной программы.

Процесс выключения Linux

Часто для выключения Linux из терминала используется утилита shutdown. Есть также команды poweroff, halt, но они для нестандартных случаев. Также выключить linux из консоли можно с помощью сочетаний клавиш SysRQ. Но сначала давайте рассмотрим синтаксис команды shutdown. Естественно, команда shutdown в Linux или любая другая не самостоятельно завершает работу системы и выключает компьютер. Она всего лишь передает запрос на выключение системе инициализации, а затем ядру. А уже они выполняют ряд сложных операций по подготовке и выключению компьютера. Если кратко, то вот они:

  • Завершение процессов пользователя.
  • Сигнал SIGTERM всем процессам.
  • Сигнал SIGKILL всем процессам.
  • Монтирование файловых систем в режиме только для чтения.
  • Подготовка внешних устройств к отключению.
  • Блокировка пространства пользователя, чтобы гарантировать, что ни один код пользователя больше не будет запущен.
  • Завершение работы и отключение питания большинства периферических устройств.
  • Отключение питания компьютера.

Теперь вы понимаете суть процесса выключения и то почему нельзя просто выдернуть шнур питания с розетки. Если это сделать, компьютер отключится моментально и не выполнит всех необходимых операций, а это может грозить потерей не сохраненных или даже недавно сохраненных данных, повреждением файловой системы и т д. Поэтому желательно выключать компьютер правильно с помощью shutdown или других специальных утилит.

Синтаксис и опции shutdown

Синтаксис команды очень простой:

Вот основные опции утилиты:

Вот в принципе и все опции утилиты, их больше чем достаточно для такого простого действия. Теперь можно переходить к примерам, но сначала давайте рассмотрим, что же происходит во время включения Linux.

Выключение компьютера в Linux

1. shutdown

Самая простая и самая часто используемая команда выключения компьютера linux, отключит компьютер немедленно:

sudo shutdown -h now

Как видите, используется обычное выключение, и константа времени now, тоесть сейчас.

Теперь попробуем запланировать выключение компьютера linux через пять минут:

sudo shutdown -h +5 "Компьютер будет выключен через 5 минут"

sudo shutdown -c

Точно так же мы можем указать точное время выключения, например в девять вечера:

sudo shutdown -h 21:00

Как я уже говорил, не только команда shutdown linux умеет выключать компьютер, есть еще несколько утилит способных на это. Рассмотрим их тоже.

2. reboot

Команда reboot обычно используется для перезагрузки системы, но она также умеет выключать компьютер. Мы не будем ее подробно рассматривать, потому, что она еще проще команды shutdown. Для выключения нужно задать опцию -p:

3. halt

Эта команда тоже выключает компьютер. Только делает она это очень по-своему. Она не выполняет никаких подготовительных действий перед выключением, а просто отключает питание:

Использование halt может повредить систему

4. poweroff

Это аналог halt, делает в точности то же самое:

5. SysRQ

Помните, в начале статьи, я говорил о сочетании клавиш для включения компьютера? Рассмотрим этот вопрос подробнее.

SysRQ - это подсистема, реализованная на уровне ядра. Ядро обрабатывает все нажатия клавиш, а с помощью этой подсистемы, оно может принимать от пользователя команды, даже когда система полностью зависла. Основное предназначение этой подсистемы - работа с компьютером в проблемных ситуациях, например, если вы думаете что ваш компьютер заразил вирус, или компьютер завис и его нужно выключить. Для доступа к SysRq используются сочетания клавиш Alt+PrtScr+номер

Самое интересное, что мы можем выполнить безопасное выключение компьютера linux. Для этого зажмите клавиши Alt + PrtScr и поочередно нажимайте:

  • R - разблокировать клавиатуру;
  • E - послать всем процессам сигнал SIGTERM;
  • I - послать всем процессам сигнал SIGKILL;
  • S - перенести все данные из кеша файловых систем на диск;
  • U - перемонтировать файловые системы только для чтения;
  • B - перезагрузить.

Также вместо всего этого можно воспользоваться сочетанием клавиш Alt+PrtScr+O, в таком случае, вся процедура будет выполнена автоматически, эта команда поддерживается не всеми ядрами.

6. Графический интерфейс

Выключить компьютер в графическом интерфейсе ещё проще. Для этого кликните по иконке выключения в правом верхнем углу, а затем выберите Выключить/Завершить сеанс, затем Выключение.. и снова Выключить:

Выводы

Теперь вы знаете все что нужно, о том, как выключить Linux через терминал. Если вас застигнет врасплох ошибка или зависание компьютера, вы знаете что делать. Если остались вопросы - пишите в комментариях!

Чтобы выполнить скрипт при выключении или перезагрузке:

сохраните ваш скрипт в /etc/rc6.d Сделайте его исполняемым: sudo chmod +x K99_script

5] Скрипт в rc6.d должен быть без расширения .sh. Имя вашего скрипта должно начинаться с K99 для запуска в нужное время. Сценарии в этом каталоге выполняются в алфавитном порядке.

В самом деле. Именование его правильно, так что он работает в нужное время, очень важно. – shivams 9 May 2015 в 14:01 Я поместил скрипт в /etc/rc6.d, и он не запускался при завершении работы. Я положил его в /etc/rc0.d, и он запустился при завершении работы. Вероятно, rc.6 предназначен только для перезагрузки. – Erel Segal-Halevi 29 October 2015 в 21:24 @Erel Segal-Halevi Я просто попробовал добавить скрипт K99 в /etc/rc6.d, и он не выполнялся. Если посмотреть на другие скрипты, есть строка ** bold K10reboot - & gt; ../init.d/reboot **, так что он выглядит как скрипт K99 НИКОГДА не будет выполнен !! – David Walker 17 July 2016 в 12:06 Создайте исполняемый файл оболочки с вашим скриптом в каталоге /etc/init.d/. Поскольку это должно быть выполнено во время выключения или перезагрузки, необходимо создать программные ссылки в /etc/rc0.d/ и /etc/rc6.d chmod изменяет флаги разрешений целевой ссылки, что одинаково для обоих аргументов. Указание их обоих является избыточным. – David Foerster 15 October 2014 в 06:36

С помощью systemd вы создаете один или два файла для вызова ваших сценариев с использованием приведенных ниже шаблонов и выполнения нескольких команд. Простой.

Версия GUI

Сначала создайте сценарии, которые вы хотите запустить при запуске и / или выключении. Просто сделайте это, если вам не нужны оба. Я создал .scopening_atstart и .scfullcopy_atend.

Сначала убедитесь, что они оба исполняются, щелкнув правой кнопкой мыши файл, выбрав свойства и убедившись, что под разрешениями вы отметили «Разрешить» исполняемый файл как программа.

Два созданных мной файла заполняют и сохраняют содержимое ramdisk. Они также создают файл в моем домашнем каталоге, чтобы доказать, что служба работает. Они были в форме:

Затем я открыл свой файловый менеджер как root, открыл /etc/systemd/system и создал файл startup.service и файл save-ramdisk.service. Очевидно, вы можете выбрать свои собственные имена, а общие имена могли включать в себя файл запуска johns_start.service и файл выключения, называемый johns_shutdown.service. Просто не выбирайте существующие имена сервисов.

Вы можете использовать те же служебные файлы, заменяя полный путь к исполняемому скрипту для моего. [ ! d17]

Затем для каждого из них выполните команду systemctl, чтобы включить имя_файла_имя (но без службы суффиксов). Итак, мой первый был systemctl enable startup

Перезагрузите компьютер один раз, чтобы запустить службы. Служба запуска будет выполняться всякий раз, когда systemd вводит многопользовательскую цель и службу остановки, когда она выходит из многопользовательской цели. Ниже будут описаны альтернативные служебные файлы с различными условиями активации.

Дополнительные полезные команды:

systemctl включен запуск systemctl is-active startup systemctl restart startup

CLI (Command Line) Version

В этом описании предполагается, что вы работаете из вашего домашнего каталога, а не / home / john, используйте sudo по мере необходимости и ваш выбор редактора, где я пишу vim или svim.

Создайте два файла, как указано выше, или в этом примере один файл для работы с задачами запуска и завершения. Я буду выполнять скрипты в своем домашнем каталоге, но @don_crissti показывает некоторые альтернативы в Stack Exchange.

и копирует в файле содержимое:

Затем Включить службу с помощью команду:

и перезагрузите вашу систему, после чего службы будут активны. Команды systemctl is-enabled start_and_stop и systemctl is-active start_and_stop могут использоваться для мониторинга ваших новых сервисов.

Изменение условий триггера для выключения

42] Файлы, созданные выше, используют открытую или закрытую многопользовательскую среду для запуска запуска скриптов. В приведенном ниже файле используется начало четырех потенциальных процессов выключения для запуска его скриптов. Добавление или удаление целей на линии «Перед линией» + «WantedBy» позволит вам сделать более точные различия:

Этот файл был предложен во втором ответе Stack Exchange , но я не смог получить он будет работать, пока я не добавлю раздел «Установка».

Снова отредактируйте скрипт в /etc/systemd/service/ и включите его, используя systemctl enable your_file_name. Когда я сменил цели, я использовал команду systemclt disable file_name, а затем снова включил ее, которая привязала ее к целевым каталогам. Перезагрузитесь, и служба будет работать.


При разработке под linux возникают задачи создания интерактивных скриптов, выполняемых при включении или завершении работы системы. В system V это делалось легко, но с systemd вносит коррективы. Зато оно умеет свои таймеры.

Зачем нужны target

Часто пишут, что target служат аналогом runlevel в system V -init. В корне не согласен. Их больше и можно разделять пакеты по группам и, к примеру, запускать одной командой группу сервисов, выполнять дополнительные действия. Кроме того, у них нет иерархии, только зависимости.

Пример target при включении(обзор возможности) с запуском интерактивного скрипта

Описание самого target:

Данный target запустится, когда будет запущен multi-user.target и вызовет installer.service. При этом таких сервисов может быть несколько.

И наконец, пример выполняемого скрипта:

Самое главное — выбрать final.target — target, к которому система должна придти при запуске. В процессе запуска systemd пройдёт по зависимостям и запустит всё нужное.
Выбрать final.target можно разными способами, я использовал для этого опцию загрузчика.

Итоговый запуск выглядит так:

  1. Стартует загрузчик
  2. Загрузчик начинает запуск прошивки, передавая параметр final.target
  3. Systemd начинает запуск системы. Последовательно идёт к installer.target или work.target от basic.target через их зависимости (например,multi-user.target). Последние и приводят систему к работе в нужном режиме

Подготовка прошивки к запуску

При создании прошивок всегда возникает задача восстановления состояния системы при старте и его сохранении при выключении. Под состоянием подразумеваются конфигурационные файлы, дампы базы данных, настройки интерфейсов и тд.

Systemd запускает процессу в одном таргете параллельно. Есть зависимости, которые позволяют определить последовательность запуска скриптов.

  1. Система стартует
  2. Запускается сервис settings_restore.service.Он проверяет наличие файла settings.txt в разделе с данными. Если его нет, то на его место кладётся эталонный файл.Далее происходит восстановление настроек системы:
    • пароля администратора
    • hostname,
    • часового пояс
    • локаль
    • Определение, весь ли носитель используется. По умолчанию размер образа небольшой — для удобства копирования и записи на носитель. При старте проверяется — есть ли ещё неиспользуемое место. Если есть — диск переразбивается.
    • Генерация machine-id из MAC-адреса. Это важно для получения одного и того же адреса по DHCP
    • Настройки сети
    • Ограничивается размер логов
    • Подготавливается к работа внешний диск(если включена соответствующая опция и диск новый)
  3. Запускаться postgresq
  4. запускается сервис restore. Он нужен для подготовки самого zabbix и его базы данных:
    • Проверяется, есть ли уже база данных zabbix. Если нет — создается из инициализирующих дампов(идут в поставке zabbix)
    • создается список часовых поясов (нужно для их отображения в web-интерфейсе)
    • Находится текущий IP, он выводится в issue (приглашение для входа в консоли)
  5. Меняется приглашение — появляется фраза Ready to work
  6. Прошивка готова к работе

Важны файлы сервисов, именно они выставляют последовательность их запуска

Как видно, я поставил зависимости, что бы сначала отработал мой скрипт, а только потом поднималась сеть и стартовала СУБД.

И второй сервис(подготовка zabbix)

Здесь немного сложнее.Запуск так же в multi-user.target, но ПОСЛЕ запуска СУБД postgresql и моего setting_restore. Но ПЕРЕД запуском служб zabbix.

Сервис с таймером для logrotate

Systemd может заменить CRON. Серьезно. Причем точность не до минуты, а до секунды(а вдруг понадобится).А можно создать монотонный таймер, вызываемый по таймауту от события.
Именно монотонный таймер, считающий время от запуска машины, я и создал.
Для этого потребуется 2 файла
logrotateTimer.service — собственно описание сервиса:

Всё просто — описание команда запуска.
Второй файл logrotateTimer.timer — вот он и задает работу таймеров:

  • описание таймера
  • Время первого запуска, начиная от загрузки систем
  • период дальнейших запусков
  • Зависимость от службы таймеров.Фактически, это строка и делает таймер

Интерактивный скрипт при выключении и свой таргет выключения

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

А дело в том, что команды, запускаемые опцией ExecOnStop выполняются вне TTY! Проверить просто — вставьте команду tty и сохраните её вывод.

Поэтому я реализовал выключение через свой таргет. На 100% правильность не претендую, но это работает!
Как это делалось(в общих чертах):
Создал таргет my_shutdown.target, который ни от кого не зависел:
my_shutdown.target

При переходе в этот таргет(через systemctl isolate my_shutdwn.target), он запускал сервис my_shutdown.service, задача которого простая — выполнить скрипт my_shutdown.sh:

  • Внутри этого скрипта я выполняю нужные действия. Можно в таргет добавить много скриптов, для гибкости и удобства:

Примечание. Использование файлов /tmp/reboot и /tmp/shutdown. Нельзя вызвать target с параметрами. Можно только service.

Но я использую target, что бы иметь гибкость в работе и гарантированный порядок выполнения действий.

Однако, самое интересное было потом. Машину же надо выключить/перезагрузить. И тут есть 2 варианта:

  • Заменить команды reboot,shutdown и прочие(они все равно являются симлинками на systemctl) на свой скрипт.Внутри скрипта — переход в my_shutdown.target. А скрипты внутри таргета потом вызывают напрямую systemctl, например, systemctl reboot
  • Более простой, но мне не нравящийся вариант. Во всех интерфейсах вызывать не shutdown/reboot/прочие, а напрямую вызывать таргет systemctl isolate my_shutdown.target

Я выбрал первый вариант. В systemd reboot(как и poweroff) являются симлинками на systemd.

Читайте также: