Время на прочтение
5 мин
Количество просмотров 79K
Добрый вечер, Habrahabr!
Сегодня мы научимся перезагружаться из Linux прямиком в Windows и обратно всего за один (двойной) клик.
Дано:
- Два диска с GPT с разными ОС
- Материнская плата с UEFI и отключеным Legacy Mode
- Windows, которую бережно поставили с полной поддержкой UEFI
- Linux (у меня Manjaro), который бережно поставили, выпилив любое упоминание GRUB и прочих старомодных вещей
- rEFInd — красивый менеджер загрузки (нет, не загрузчик)
Надо:
- Написать два скрипта на *sh и cmd (bat), которые позволят перезагрузиться в нужную ОС
Примечания:
- Рабочие варианты обозначены, как Решение, остальное — мои рассуждения и описание пути к цели.
- Я сознательно опускаю описание тех деталей, которые не относятся к сути настройки, либо легко варьируются. Упоминаются же эти детали потому, что для меня они не были очевидны на момент настройки, поэтому статья становится более понятной для неискушенных читателей, которые не будут видеть в ней инструкцию по рисованию совы.
- Почему стоит быть осторожным при модификации NVRAM
Linux:
Linux — прекрасная база для работы с компьютером, поэтому всё, что нам нужно, уже есть в репозиториях, а коллективный разум сообщества знает всё и всегда готов помочь. Поэтому, после недолгого изучения интернета, ставим efibootmgr:
У меня это было так
sudo pacman -S efibootmgr
Отлично, теперь запускаем:
sudo efibootmgr
Видим что-то вроде этого
Timeout: 1 seconds
BootOrder: 0001,0000
Boot0000* Windows Boot Manager
Boot0001* rEFInd Boot Manager
Внимательные читатели уже наверняка заметили, что в выводе что-то не так, но тогда я был окрылён мыслью о том, что через 15 минут буду летать между операционками без проблем, и не обратил на это должного внимания.
Ок, 3 минуты на документацию, и мы находим нужный параметр «-n«, который выставляет кастомый порядок загрузки ровно на один раз. Пробуем выполнить эту команду:
Решение
sudo efibootmgr -n 0000 && sync && reboot
И оказываемся в Windows, как того и желали. Теперь эту команду записываем в скрипт/alias/*.desktop-файл и радуемся тому, как всё здорово получилось.
Windows:
Началось всё с поиска аналога efibootmgr для Windows, которого в чистом виде, конечно же, нет. Для успокоения совести я даже попытался использовать Linux Subsystem, но это, конечно же, не сработало.
Беглый поиск по интернетам показал, что схожим функционалом по модификации NVRAM обладает утилита bcdedit. Отлично, думаю я, запускаю PowerShell из-под Администратора и пишу
bcdedit /enum firmware
Вот что я увидел
Firmware Boot Manager
---------------------
identifier {fwbootmgr}
displayorder {6893bb38-946b-11e7-b175-9301bd8a88f4}
{bootmgr}
timeout 1
Windows Boot Manager
--------------------
identifier {bootmgr}
device partition=\Device\HarddiskVolume2
path \EFI\Microsoft\Boot\bootmgfw.efi
description Windows Boot Manager
locale ru-RU
inherit {globalsettings}
default {current}
resumeobject {6893bb40-946b-11e7-b175-9301bd8a88f4}
toolsdisplayorder {memdiag}
timeout 30
Firmware Application (101fffff)
-------------------------------
identifier {6893bb38-946b-11e7-b175-9301bd8a88f4}
device partition=\Device\HarddiskVolume2
path \EFI\REFIND\REFIND_X64.EFI
description rEFInd Boot Manager
Где Linux? Куда грузиться? Ненавижу винду
На самом деле оказалось, что виновата не Windows, а я (да-да, тот самый момент для внимательных пользователей), и вот почему: rEFInd — прекрасная утилита, которая обычно, для корректной работы, требует только установить себя. Она умеет подхватывать все .efi файлы, разные дистрибутивы с разными ядрами, сама подставляет иконки. Прелесть, а не инструмент. Но это сыграло со мной злую шутку, так как оказалось, что UEFI ничего не знает про Linux, так как отсутствует соответствующий ему .efi-файл.
Поэтому презагружаемся обратно в Linux, конфигурируем systemd-boot (bootctl). Теперь всё выглядит вот так:
Timeout: 1 seconds
BootOrder: 0001,0003,0000,0002
Boot0000* Windows Boot Manager
Boot0001* rEFInd Boot Manager
Boot0002* Linux Boot Manager
Boot0003* Manjaro
Возвращаемся обратно и снова запускаем.
bcdedit /enum firmware
Вот что я увидел теперь
Firmware Boot Manager
---------------------
identifier {fwbootmgr}
displayorder {6893bb38-946b-11e7-b175-9301bd8a88f4}
{bootmgr}
{ff0bc716-c088-11e7-bf74-000acd2dac7d}
{ff0bc716-c088-11e7-bf74-000acd2dac7d}
timeout 1
Windows Boot Manager
--------------------
identifier {bootmgr}
device partition=\Device\HarddiskVolume2
path \EFI\Microsoft\Boot\bootmgfw.efi
description Windows Boot Manager
locale ru-RU
inherit {globalsettings}
default {current}
resumeobject {6893bb40-946b-11e7-b175-9301bd8a88f4}
toolsdisplayorder {memdiag}
timeout 30
Firmware Application (101fffff)
-------------------------------
identifier {6893bb38-946b-11e7-b175-9301bd8a88f4}
device partition=\Device\HarddiskVolume2
path \EFI\REFIND\REFIND_X64.EFI
description rEFInd Boot Manager
Firmware Application (101fffff)
-------------------------------
identifier {ff0bc716-c088-11e7-bf74-000acd2dac7d}
device partition=\Device\HarddiskVolume2
path \EFI\SYSTEMD\SYSTEMD-BOOTX64.EFI
description Linux Boot Manager
Firmware Application (101fffff)
-------------------------------
identifier {ff0bc717-c088-11e7-bf74-000acd2dac7d}
device partition=\Device\HarddiskVolume1
path \EFI\manjaro\vmlinuz-4.13-x86_64
description Manjaro
Тут стоит упомянуть, что проблему мне помогали решать пользователи reddit. Именно благодаря им мы имеем следующий шаг:
bcdedit /bootsequence {ff0bc716-c088-11e7-bf74-000acd2dac7d}
Где аргументом является identifier необходимого варианта — Linux Boot Manager.
Troubleshooting
Powershell не даёт нормально выполнить эту команду, ругаясь на
The entry list data is not valid as specified.
Всё из-за того, что Microsoft периодически любит что-нибудь сломать. Решение просто и элегантно — вызываем классический CMD и работаем в нём. Это можно сделать командой
cmd
Перезагружаемся и видим, что порядок загрузки не изменился, а мы оказались в первом элементе в BootOrder (у меня это был rEFInd), выбираем Windows и видим страшный привет из времен DOS, который говорит нам, что \EFI\SYSTEMD\SYSTEMD-BOOTX64.EFI не найден. Да, мы изменили параметры загрузчика Windows, но не UEFI.
Борьба с этой ошибкой заняла у меня все праздники, но ничего путного не получалось. Я уже подумывал написать на C++ небольшую программку для этого (то, что это возможно, следует из существования такого софта, как EasyUEFI).
Но тут на очередном сайте я обнаружил вот такую конструкцию
bcdedit /set {bootmgr} path ....
И тут меня осенило, что можно прямо сказать bcdedit что и куда писать. Дальше стоило только проверить догадку:
Решение
bcdedit.exe /set {fwbootmgr} bootsequence {ff0bc716-c088-11e7-bf74-000acd2dac7d} /addfirst
Тут важно, что мы явно сказали писать не в {bootmgr} (как он, видимо, делает по-умолчанию), а в {fwbootmgr}, что и является нашими настройками UEFI.
Перезагружаемся, и всё работает так, как мы этого хотели. Сохраняем это дело в bat/lnk, дописываем
shutdown /r /t 0
Выставляем запуск из-под администратора и готово!
Спасибо за внимание! Буду крайне рад замечаниям по технической части в комментариях, замечаниям по оформлению — в ЛС.
There is a grub command just to do so, it is grub-reboot
.
It seems to only work when you have grub configured to start with the last saved entry. So if you have not already done so, modify /etc/default/grub
and set
GRUB_DEFAULT=saved
then update grub configuration file:
sudo update-grub
From now on, at each boot grub will start the last used entry.
Now, if you want to set in advance what should be the system to boot the next time, use
sudo grub-reboot ENTRY
where ENTRY
could be a number relative to a menu entry (numbered starting from 0), or an exact menu entry title, for example
sudo grub-reboot "Microsoft Windows XP Professional (on /dev/sda1)"
This command can easily be made available as a launcher
#!/usr/bin/env xdg-open
#
# save as ~/Desktop/reboot-into-windows.desktop
#
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Exec=sh -c 'gksu "grub-reboot 2" && gnome-session-save --shutdown-dialog'
Name=Reboot into Windows
Icon=gnome-panel-launcher
but I don’t know how it could be integrated into the system menu.
You can obtain the available menu entry title with
sed -n '/menuentry/s/.*\(["'\''].*["'\'']\).*/\1/p' /boot/grub/grub.cfg
Понадобилось мне внезапно ребутнуть седьмую Windows из под пингвина. Оказалось, что это как два пальца об асфальт. Итак…
Для удалённой перезагрузки Windows-машины из Linux, нам понадобится установить пакет samba-common…
И выполнить следующую команду для перезагрузки удаленной Windows-машины:
net rpc shutdown -r -C «комментарий» -f -I «netname» -U «username» -t «N»
где параметры обозначают следующее:
-r или -reboot — перезагрузка компьютера вместо выключения
-f или -force — принудительное выполнение
-I — сетевое имя машины, или её IP адрес
-U — имя пользователя, имеющего соответствующие права на данной машине
-t или -timeout=«N» — задержка до начала выключения/перезагрузки
(по умолчанию равна 20 секундам)
-C или -comment=«комментарий» — комментарий, показываемый в информационном окне
При выполнении команды, появится запрос пароля для пользователя username.
Можно пароль указать сразу, введя имя пользователя в формате «username%password»
Источник
28 декабря 2011. Комментарии: Комментарии к записи Удалённая перезагрузка Windows-машины из Linux отключены. Размещено в Linux
| Posted:
If you’re dual-boot Ubuntu and Windows, you can use a simple command (or create a menu shortcut for it) to easily restart in Windows from Ubuntu. This should actually work with any Grub entry, not just Windows (so if you using multiple Linux distributions, it will work with that too).
Note: this will only work with GRUB 2.
This command will not change the GRUB menu entries order. When GRUB starts, the first entry in the menu list is highlighted — this command will highlight the menu entry you set and will boot it if you don’t select a different option (so the GRUB menu will still be displayed if you’ve set a GRUB timeout higher than 0).
1. Edit /etc/default/grub:
sudo gedit /etc/default/grub
and modify the «GRUB_DEFAULT=0» value (it should be on line 4) from «0» to «saved» (without the quotes) so that it looks like this:
GRUB_DEFAULT=saved
Then save the file.
2. Update GRUB:
sudo update-grub
3. Now to reboot Ubuntu in Windows or some other OS, run the following command:
sudo grub-reboot X
where X is the menuentry position (starting with 0 as the first entry) of the OS you want to restart in from the GRUB menu. So if Windows is the 4th option in the GRUB menu, you would run «sudo grub-reboot 3». You can also use the exact menu entry instead of the menuentry position (like «Windows 7 (on /dev/sda1)») but entering just a number should be easier to remember. The grub-reboot will set the default boot entry for the next boot only.
Then simply restart your computer and it should boot in Windows or whatever GRUB menuentry choice you’ve entered for the above command.
4. (optional) For easy access, you can make a script which automatically makes your computer restart in predefined OS:
#!/bin/bash
gksu grub-reboot X
gksu reboot
Again change «X» for the GRUB menuentry number you want to boot in (counting from 0) and make a shortcut for this script on your panel for example.
Tagged with:
grub2
linux
tips n tricks
ubuntu
windows
Я ищу способ перезагрузки в Windows из Ubuntu в системе с двойной загрузкой 10.10 / Vista. Конкретный вариант использования заключается в том, что я хотел бы иметь возможность подключиться по ssh к моему работающему экземпляру Ubuntu и выполнить команду, которая инициирует перезагрузку непосредственно в Windows.
Я нашел многообещающее сообщение в блоге , но предлагаемый сценарий не работает:
#!/bin/bash
WINDOWS_ENTRY=`grep menuentry /boot/grub/grub.cfg | grep --line-number Windows`
MENU_NUMBER=$(( `echo $WINDOWS_ENTRY | sed -e "s/:.*//"` - 1 ))
sudo grub-reboot $MENU_NUMBER
sudo reboot
man grub-reboot
не сильно помогает, но, похоже, ведет меня в правильном направлении:
устанавливает загрузочную запись по умолчанию для GRUB, только для следующей загрузки
WINDOWS_ENTRY=`grep menuentry /boot/grub/grub.cfg | grep --line-number Windows` MENU_NUMBER=$(( `echo $WINDOWS_ENTRY | sed -e "s/:.*//"` - 1 )) echo $MENU_NUMBER
Возвращает ожидаемое значение, но при перезагрузка первый пункт меню все еще выделен. Есть идеи, почему это не работает, или предложения для других решений?
задан
19 December 2010 в 23:54
поделиться
8 ответов
-
Сначала нужно отредактировать grub.
sudo gedit /etc/default/grub
-
Ищите строку GRUB_DEFAULT=0 и измените ее на GRUB_DEFAULT=saved
-
Обновите grub следующей командой.
sudo update-grub
-
Теперь создайте файл сценария,
sudo gedit switch-to-windows.sh
-
Затем добавь эти строки.
#!/bin/bash WINDOWS_ENTRY=`grep menuentry /boot/grub/grub.cfg | grep --line-номер Windows`. MENU_NUMBER=$(( `echo $WINDOWS_ENTRY | sed -e "s/:.*//" ` - 1 )) sudo grub-reboot $MENU_NUMBER перезагрузка с нуля
-
Сделайте скрипт исполняемым.
sudo chmod +x switch-to-windows.sh
-
И теперь вы можете запустить этот скрипт из терминала для перезагрузки в windows.
./switch-to-windows.sh
-
Или вы можете выполнить следующую команду в терминале
sudo grub-reboot X.
-
Где X — позиция меню, в которой находится операционная система, которую вы хотите перезапустить из меню GRUB (начиная с 0, как первая запись)
Пример:
- Если это ваше меню grub и если вы хотите загрузиться в окна, то вы должны указать значение X как 5.
-
sudo grub-reboot 5
- Вы также можете создать пусковую установку для вышеуказанной команды, так что двойной щелчок по пусковой установке перезагрузится в windows.
ответ дан Mgs M Rizqi Fadhlurrahman
19 December 2010 в 23:54
поделиться
Для этого есть команда grub-rebootgrub-reboot
.
Похоже, что она работает только в том случае, если у вас настроен grub на начало работы с последней сохраненной записью. Так что если вы ещё этого не сделали, измените /etc/default/grub
и установите
GRUB_DEFAULT=saved
, затем обновите файл конфигурации grub:
sudo update-grub
С этого момента, на каждом загрузочном grub будет запускаться последняя использованная запись.
Теперь, если вы хотите задать заранее, какой должна быть система для загрузки в следующий раз, используйте
sudo grub-reboot ENTRY
, где ENTRY
может быть числом относительно пункта меню (пронумерованным, начиная с 0), или точным заголовком пункта меню, например
sudo grub-reboot "Microsoft Windows XP Professional (on /dev/sda1)"
Эта команда может быть легко доступна как пусковая установка
#!/usr/bin/env xdg-open
#
# save as ~/Desktop/reboot-into-windows.desktop
#
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Exec=sh -c 'gksu "grub-reboot 2" && gnome-session-save --shutdown-dialog'
Name=Reboot into Windows
Icon=gnome-panel-launcher
, но я не знаю, как она может быть интегрирована в системное меню.
Вы можете получить доступное заглавие пункта меню с помощью
sed -n '/menuentry/s/.*\(["'\''].*["'\'']\).*/\1/p' /boot/grub/grub.cfg
ответ дан enzotib
19 December 2010 в 23:54
поделиться
Насколько я понял, это будет не совсем то, что вы хотите, но я думаю, что это довольно близко. Просто перейдите по ссылке webupdate article.
ответ дан N.N.
19 December 2010 в 23:54
поделиться
Думаю, я нашел еще более приятный способ для людей, которые хотят сделать то же самое, находясь локально в своем компьютере без ssh.
Решение по перезагрузке в конкретную систему, выбранную через единую пусковую установку, было только что размещено на webupd8.
Смотрите http://www.webupd8.org/2011/05/custom-unity-launcher-to-reboot-in.html
Я знаю, что это не совсем то, о чем идет речь, но если у кого-то есть похожий вопрос позже, это может быть полезно.
ответ дан K. Hendrik
19 December 2010 в 23:54
поделиться
Просто отредактируйте /boot/grub/grub.cfg
и измените запись по умолчанию, чтобы она указывала на запись, которую вы хотите загрузить. Значение может быть либо порядковым номером записи (начиная с нуля для первой), либо вы можете поместить полное название нужной записи в кавычки.
ответ дан enzotib
19 December 2010 в 23:54
поделиться
Не уверен, что это на 100% сработает и в убунту, но я однажды сделал эту работу на центробежной машине
, в основном, вам придется сказать grub.conf, какой id # из grub.conf должен запуститься следующим. ID # можно узнать по
echo `sudo grep ^title /boot/grub/grub.conf | grep -n Windows | cut -f 1 -d:`-1
так что в моем случае это будет, например, вывод «4-1», так как четвертая запись в моем grub.conf содержит текст «Windows». (Замените это на фактическое имя записи (также частично), которое вы хотите использовать.
Тогда вы можете скормить это в grub как:
echo "savedefault --stage2=/boot/grub/stage2 --default=4-1 --once" | sudo /sbin/grub
и при следующей перезагрузке он должен автоматически загрузить запись, которую вы сказали ему.
это все может быть объединено в скрипт типа:
#!/bin/sh
let NEWBOOT=`sudo grep ^title /boot/grub/grub.conf | grep -n Windows | cut -f 1 -d:`-1
echo Booting $NEWBOOT - `sudo grep ^title.\*Windows /boot/grub/grub.conf`
echo "savedefault --stage2=/boot/grub/stage2 --default=$NEWBOOT --once" | sudo /sbin/grub
sudo reboot
скрипт автоматически определит, какой элемент из вашего grub.conf соответствует тексту «Windows», будет кормить это в grub, чтобы сказать, что должно быть загружено при следующей загрузке и
перезагрузит ваш компьютер
для gui вы можете, например, добавить иконку ярлыка на ваш рабочий стол, чтобы достичь этого.
ответ дан Roland Kohn
19 December 2010 в 23:54
поделиться
Так что для меня лучше всего было создать следующий скрипт с помощью команды grub-reboot
#!/bin/bash
WINDOWS_TITLE=$(grep -i 'windows' /boot/grub/grub.cfg|grep "^[^#;]"|cut -d"'" -f2)
sudo grub-reboot "$WINDOWS_TITLE"
echo "Your computer will reboot on ${WINDOWS_TITLE} in 3 seconds, press Ctrl+C if you want to abord it"
sleep 3 && sudo reboot
ответ дан Philippe Gachoud
19 December 2010 в 23:54
поделиться
Информация обо всех была полезна для меня, но в конце концов я все еще не мог изменить настройки grub по умолчанию и перезапустить их одним щелчком мыши. Повозившись в течение 2 часов, я обнаружил эту программу, которая является той же самой, что мы все пытаемся создать, и через 5 минут я перезагружаюсь в Windows.
Спасибо всем, вот ссылка на читера для тех, кто тоже сдаётся.
http://www.webupd8.org/2013/01/unity-reboot-launcher-to-quickly-reboot.html
ответ дан Mickey Brown
19 December 2010 в 23:54
поделиться