Выполнить команду перед выключением / перезагрузкой [duplicate]

19

У меня есть машина под управлением пары бродячих ВМ. У меня проблема в том, что иногда я забываю отключить эти виртуальные машины перед тем, как выключить или перезагрузить компьютер. Из-за этого моя машина застряла с этим сообщением:waiting for vboxnet0 to become free

Я искал решения и нашел эту страницу:

http://en.kioskea.net/faq/3348-ubuntu-executing-a-script-at-startup-and-shutdown

Я пытался, что они для выключения, но это не работает.

Я написал файл sh для этой команды:

#!/bin/bash

cd ~/workspace/git/mediaservice
vagrant halt

какие-либо предложения?

SERPRO
источник
4
Метод в ссылке действителен и работает на всех версиях Linux, поэтому ваш скрипт неверен;) Пользователь не известен при завершении работы, поскольку он выполняется пользователем root. Так что опустите "~" и сделайте полный путь.
Rinzwind
Это работает? Я следовал тому же мануэлю, как gist.github.com/ymc-geha/8416723, но у меня не работал на Ubuntu 14.04
user2135804
@ user2135804 Я думал, что это сработало .. но на самом деле это не сработало для Vagrant .. Я попробовал другие вещи, и это сработало хорошо.
SERPRO
1
Кстати, ошибка, которую вы описываете, здесь .
Гарретт
1
Как видно из сообщения об ошибке, это было исправлено и будет включено в VirtualBox 4.3.29.
Гаррет

Ответы:

12

Если ваши бродячие виртуальные машины используют VirtualBox, вы можете изменить / etc / default / virtualbox и изменить строку, которая гласит:

SHUTDOWN_USERS=""

в

SHUTDOWN_USERS="all"

Это исправило это для меня на Ubuntu 14.04

GaryBishop
источник
1
На самом деле в виртуальном ящике есть открытый билет, связанный с этим. virtualbox.org/ticket/12264 . Я бы предложил использовать SHUTDOWN_USERS=`cut -d: -f1 /etc/passwd`вместоSHUTDOWN_USERS="all"
running.t
Я также на Ubuntu 14.04 с Vagrant, используя VirtualBox, но у меня нет никакого /etc/default/virtualboxфайла ...
Гаррет
21

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

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

Примечания:

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

источник

Maythux
источник
1
В самом деле. Называя его правильно, чтобы он работал в нужное время, очень важно.
Шивамс
2
Я поместил скрипт в /etc/rc6.d, и он не запустился при выключении. Я положил его в /etc/rc0.d и он запустился при выключении. Вероятно, rc.6 только для перезагрузки.
Эрель Сегал-Халеви
2
@Erel Segal-Halevi Я только что попытался добавить скрипт K99 в /etc/rc6.d, но он не запустился. Если посмотреть на другие скрипты, есть строка ** жирный K10reboot -> ../init.d/reboot ** код, так что похоже, что скрипт K99 НИКОГДА не будет выполнен !!
Дэвид Уокер
Ответ от Ravi ниже - лучший выбор, потому что он использует символические ссылки, чтобы обеспечить выполнение сценария как при завершении работы, так и при перезагрузке. Я также думаю, что большинство системных файлов используют такой подход.
Эдди
rc.6, кажется, только для перезагрузки, как уже упоминалось. Смотрите
Aelian
12

Как это сделать с помощью Systemd (это проще)

Теперь, когда варианты Ubuntu и Mint перешли на systemd, я обнаружил, что мои старые решения, основанные на вышеизложенном, были менее удовлетворительными. Я искал в Интернете, чтобы выяснить, как это сделать с помощью systemd, и в итоге объединил чужую мудрость и задокументировал ее как пост в блоге на blogspot.com.au, содержащий следующее руководство.

С помощью 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 входит в многопользовательскую цель, и службу остановки, когда она выходит из многопользовательской цели. Альтернативные сервисные файлы с различными условиями активации будут описаны ниже.

Дополнительные полезные команды включают в себя:

systemctl активирован при запуске
systemctl активен при запуске
systemctl перезапустить запуск

Больше можно найти по ссылке выше.



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» позволит вам сделать более четкие различия:

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

Снова отредактируйте скрипт /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
Иоанн 9631
источник
7
Полегче? проще чем что? легче чем восхождение на Эверест? любое другое решение, опубликованное здесь, проще, чем это ...
Фран Марзоа
1
Вау, это полный и прилично написанный ответ, и что каждый должен делать - проблемы с именами в /etc/rc6.d и путаница указывают на то, что это не очень хорошие ответы. Если процедура проста, то она не обязательно может безопасно достичь ее конца. Смотрите раздел [Install] - вы можете быть уверены, что ваш скрипт будет выполнен в нужное время. Кроме того, поскольку ответ длинный, это не значит, что он сложный! Спасибо Кстати, John9631, этот ответ является совершенным , и будет иметь неоценимое значение в создании безопасных и эффективных сценариев в критически важных момент времени ...
мельник горилла
11
  1. Создайте исполняемый файл оболочки с вашим скриптом в каталоге /etc/init.d/.

  2. Так как это должно выполняться во время выключения или перезагрузки, необходимо создать программные ссылки в /etc/rc0.d/ и /etc/rc6.d

Пример:

sudo ln -s /etc/init.d/<your_file> /etc/rc0.d/k99stop_vm
sudo ln -s /etc/init.d/<your_file> /etc/rc6.d/k99stop_vm
sudo chmod a+x /etc/init.d/<your_file>
Ravi
источник
chmodизменяет флаги разрешения цели ссылки, которая одинакова для обоих аргументов. Указание их обоих является излишним.
Дэвид Фёрстер
2

Вы можете найти решение здесь: Приостановить / возобновить работу всех ящиков Vagrant при выключении / запуске системы .

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

Установка

Отредактируйте /etc/init.d/vagrant-boxesи вставьте скрипт из вышеприведенной статьи и сохраните. Или загрузите его отсюда и сохраните в /etc/init.d/vagrant-boxes. На Debian / Ubuntu и т. Д., Запустите

# update-rc.d vagrant-boxes defaults 99 01

Номер 99 является порядковым номером и должен быть больше, чем (в моем случае Virtualbox номер 20, который, кстати, используется по умолчанию в дистрибутивах Debian). Второй номер - это последовательность при выключении компьютера. Таким образом, это может быть хорошо сделать в первую очередь.

Мильковский
источник
2

Для Ubuntu 14.10 вы что-то вроде RC04неRC99

Что делать с нуля

  1. Создать скрипт на /etc/init.d/scriptName
  2. Ссылка через ln -s /etc/rc6.d/K04scriptName /etc/init.d/scriptName

Шаги, которые я прошел

  1. Я безуспешно пытался использовать Ubuntu - Выполнение скрипта при запуске и завершении работы
  2. Я нашел скрипт выключения Ubuntu 14.10 с помощью rc0.d (rc6.d, rc.d)
  3. Я изменил с /etc/rc6.d/RC99linkName на /etc/rc6.d/RC04linkName, и это работает
Энтони Астидж
источник