Выполнить скрипт при выходе / перезагрузке / выключении в Ubuntu


30

Я хотел бы запустить .shфайл, используя bash при выходе из системы и выключении Ubuntu. Я искал в Интернете и нашел только исправления для KDE и GNOME. Сценарий прост, мне просто нужно знать, могу ли я добавить строку кода в файл «logoff / shutdown» или мне нужно сослаться на нее в другом сценарии.


1
Поместите символические ссылки на исполняемые файлы в /etc/init.d в /etc/rc0.d и /etc/rc6.d
еще один пользователь

2
Пожалуйста, рассмотрите возможность принятия обновленного ответа (используя systemd), чтобы люди увидели его сверху.
Джонатан Ю.

Ответы:


18

Чтобы выполнить скрипт при выходе из системы:

Добавьте следующую строку:

session-cleanup-script=/path/to/script

в /etc/lightdm/lightdm.confфайле.

Вы должны перезапустить lightdm, чтобы это изменение вступило в силу. Для этого войдите в tty1, используя Ctrl+ Alt+ F1, войдите под своим именем пользователя и паролем и выполните следующую команду:

sudo service lightdm restart

Примечание: использование Ctrl+ Alt+ , F7чтобы переключиться на графическую сессию

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

  1. Поместите ваш сценарий в /etc/rc0.d
  2. Сделайте его исполняемым: sudo chmod +x K99_script
  3. Заметки:
    • Сценарии в этом каталоге выполняются в алфавитном порядке.
    • Имя вашего скрипта должно начинаться с K99запуска в нужное время.

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

  1. Поместите ваш сценарий в /etc/rc6.d
  2. Сделайте его исполняемым: sudo chmod +x K99_script
  3. Заметки:
    • Сценарии в этом каталоге выполняются в алфавитном порядке.
    • Имя вашего скрипта должно начинаться с K99запуска в нужное время.

Источники:


4
Это обычная назвать сценарии , начиная с Kдля «убийства» и Sдля «Start».
Кири

Что если скрипту нужны привилегии sudo? Насколько я могу судить, скрипты /etc/rc6.d запускаются от имени пользователя и не могут использовать gksudo.
Urhixidur

1
у меня не работает с 14.04, есть какие-то изменения или неуказанный важный факт?
Томасб

2
Совет K99 не подходит для выключения / перезагрузки, если вы хотите сохранить некоторые данные, потому что это происходит ПОСЛЕ размонтирования И K используется для отключения скрипта (см. /Etc/rcS.d/README), используйте S для запуска и поместите его перед размонтированием, для загрузки поместите ваш скрипт после монтирования, застрял на этом, потому что эта дезинформация, разрешенная с S в качестве первой буквы
tomasb

6
Это очень неправильно: i) имена сценариев должны начинаться с a Kдля уровней выполнения 0, 1 и 6 и Sдля уровней выполнения 2, 3, 4 и 5; ii) вам не нужно вызывать скрипт K99_foo, число просто определяет порядок запуска скриптов. Вам нужно выбрать тот, который больше остальных, если вы хотите, чтобы он запускался последним; iii) Уровень запуска 0 не для перезагрузки! ; Это для выключения. 6 для перезагрузки. iv) скрипты не должны быть в /etc/rcN.dкаталогах. Вместо этого они должны быть в /etc/init.dи связаны с /etc/rcN.d.
тердон

14

Как это сделать с помощью systemd

Если вы найдете эту ветку после июня 2016 года, Ubuntu и его производные, включая Mint, будут использовать systemd для управления инициализацией и завершением работы системы. У меня были проблемы со старым подходом, поэтому я исследовал системный подход.

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


Версия GUI

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

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

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

#!/bin/sh
cp -pru /home/john/zRamdisk/subdirectory1/* /home/john/.wine/drive_c/subdirectory1/
rm /home/john/stop_time
date +%D' '%T > /home/john/stop_time

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

[Unit]
Description=Startup Applications

[Service]
Type=oneshot
RemainAfterExit=false
ExecStart=/home/john/.scopening_atstart

[Install]
WantedBy=multi-user.target

а также

[Unit]
Description=Save Ramdisk to Wine drive C

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/john/.scfullcopy_atend

[Install]
WantedBy=multi-user.target

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

Наконец, для каждого из них выполните команду systemctl enable your_files_name (но без службы суффиксов). Так что мой первый былsystemctl enable startup

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


CLI (командная строка) версия

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

Создайте сценарии оболочки запуска и завершения работы с первой строкой #!/bin/shи сделайте их исполняемыми с помощью chmod +x my_new_filename.

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

svim /etc/systemd/system/start_and_stop.service

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

[Unit]
Description=Run Scripts at Start and Stop

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/home/john/.startup_commands  #your paths and filenames
ExecStop=/home/john/.shutdown_commands

[Install]
WantedBy=multi-user.target

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

systemctl enable start_and_stop

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


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

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

Этот файл был предложен @Matthias в Unix & Linux ответом, но я не смог его запустить, пока не добавил раздел «Установка».

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

[Unit]
Description=Do something required
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target
# This works because it is installed in the target and will be
#   executed before the target state is entered
# Also consider kexec.target

[Service]
Type=oneshot
ExecStart=/home/john/.my_script  #your path and filename

[Install]
WantedBy=halt.target reboot.target shutdown.target

1
Хотя ваш пост правильный, я бы посоветовал улучшить его, добавив пример того, как такие шаги можно выполнить с помощью систем. Пожалуйста, дайте мне знать, как только вы отредактируете свое сообщение. Спасибо и добро пожаловать в AskUbuntu
Сергей Колодяжный

Привет, Серг, ты имеешь в виду такие примеры, как в связанном посте, или ты что-то имел в виду? Во-вторых, я не уверен, как «сообщить вам», так как не могу найти механизм для связи с другим пользователем SO.
Джон 9631

Да, вы можете привести пример такой же, как в другом посте. Просто сказать «перейти по этой другой ссылке» не очень хорошо и ваш ответ выглядит ленивым. Также для связи с другим пользователем SO используйте @ перед именем пользователя, например @Serg
Сергей Колодяжный

Намного улучшилось Очень хорошо, продолжайте в том же духе!
Сергей Колодяжный

1
в соответствии с man systemd.unitсозданными пользователем файлами могут быть размещены $XDG_CONFIG_HOME/systemd/userи другие локальные пользовательские местоположения
Антониос Хаджигеоргалис
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.