Показать полную графическую версию : [решено] Узнать, MBR или GPT?
Ксеноинженер, вы пробовали проверять свою конструкцию в деле? У меня совмещение двух строк без промежуточного помещения результатов в файл disks.txt:
ECHO LIST DISK | DISKPART | FINDSTR /r /c:"\*$" > disks.txt
FOR /f "tokens=2" %%i IN (disks.txt) DO ECHO select disk %%i >> diskpart.txt && ECHO detail disk >> diskpart.txt...в аналог вашего кода:
for /f "tokens=2" %%I IN ('Echo List Disk ^| Diskpart ^| Findstr /e "Boot Загрузоч"') do echo Select Disk ^%%I > diskpart.txt && echo uniqueid disk >> diskpart.txt...не проходило - ругается то на команду echo, то на знак |. При помощи ^ вы экранировали символы |, но остаются ли последние после этого работоспособными? Кстати, при применениии конструкции "echo Select Disk ^%%I > diskpart.txt" вы получите перезапись старых значений новыми, а не накопление оных. Это не говоря уже о том, что искать подстроки "Boot Загрузоч" в результатах срабатывания команды List Disk бесполезно - их там нет.
Поиск "{" через команду uniqueid disk действительно может помочь в определении GPT-раздела. Только тут надо каждый раздел подключать и проверять поочередно, а я с помощью команды List Disk нахожу их все одним махом. Да и ничуть uniqueid disk не поможет в определении, есть ли среди GPT-дисков загрузочный, для чего я и использую detail disk.
Если честно, в вашем скрипте столько ошибок и логических нестыковок, что он в таком виде не заработает совершенно точно. Это я могу сказать даже без тестирования.
Ксеноинженер
27-04-2013, 03:14
m0nkrus, Вы были корректны. Моё недоразумение в данном случае.
Возвращаюсь к Вашему, правильному, скрипту.
Обойтись одним внешним файлом всё же можно (проверил, работает на GPT и MBR)
каретки "^" обеспечивают целостность строки echo, не разрывая цикл символами "|".
CD /d %~dp0
for /f "tokens=2" %%I IN ('echo List Disk ^| Diskpart ^| Findstr /r /c:"\*$"') do echo Select Disk %%I >> diskpart.txt && echo detail disk >> diskpart.txt
Diskpart /s diskpart.txt | findstr /e "Boot Загрузоч"
IF ERRORLEVEL 1 (
ECHO Загрузочный том размещен на MBR-разделе
) ELSE (
ECHO Загрузочный том размещен на GPT-разделе
)
)
del /q diskpart.txt
pause
остаются ли последние после этого работоспособными?
да, остаются, это как с двойным %% для переменной работает
перезапись старых значений новыми
Не подумал о нескольких gpt дисках в системе, был не прав :)
он в таком виде не заработает совершенно точно.
Что ж, с этим я смирюсь как-нибудь. Важно другое, мастер лучших в рунете сборок Windows Vista/7/8 - это Вы, уважаемый m0nkrus. Дело мастера боится.
Одно пока мне неясно, как скрыть сообщение о найденном GPT диске. @echo off почему-то не сработал?
Нагляднее (не проверялось):
for /f "tokens=2" %%I IN ('echo List Disk ^| Diskpart ^| Findstr /r /c:"\*$"') do (
> diskpart.txt (echo Select Disk %%I
echo detail disk)
)
Также можно использовать такую методику работы с diskpart.exe:
(echo select disk 0 & echo list volume) | diskpart.exe
т.е. (также не проверялось) наподобие:
for /f "tokens=2" %%I IN ('echo List Disk ^| Diskpart ^| Findstr /r /c:"\*$"') do (
(echo Select Disk %%I
echo detail disk) | diskpart.exe | findstr.exe /e "Boot Загрузоч"
IF ERRORLEVEL 1 (
ECHO Загрузочный том размещен на MBR-разделе
) ELSE (
ECHO Загрузочный том размещен на GPT-разделе
)
)
да, остаются, это как с двойным %% для переменной работает »
Это действительно полезная оптимизация.
Одно пока мне неясно, как скрыть сообщение о найденном GPT диске. @echo off почему-то не сработал? »
Это-то как раз просто. В конце команды добавить "> nul". Но в моем конкретном случае это несущественно.
Iska
Спасибо, посмотрю ваши наработки. Потестирую. Оптимально, конечно, совсем отказаться от внешних файлов.
Iska, первая конструкция рабочая, за исключением маленького нюанса. Она у вас тоже предусматривает наличие только одного GPT раздела. Надо так:
for /f "tokens=2" %%I IN ('echo List Disk ^| Diskpart ^| Findstr /r /c:"\*$"') do (
>> diskpart.txt (echo Select Disk %%I
echo detail disk)
)
Вторая конструкция тоже рабочая. Команды вы правда подобрали бессистемно. Команде, начинающейся с list без разницы, какой диск выбран. Но сама идея конструкта интересна.
Третий код снова не учитывает наличия нескольких GPT-разделов. Если их два и система размещена на первом, то на выходе скрипта мы получим, что система у нас, якобы на MBR.
Она у вас тоже предусматривает наличие только одного GPT раздела. »
m0nkrus, у меня и одного-то нет :lol:. Я потому и писал — «не проверялось». Я просто брал код из чужого поста и на его основе «лопатил». «Отлопаченное» выделял цветом.
Команды вы правда подобрали бессистемно. Команде, начинающейся с list без разницы, какой диск выбран. »
Второй пример — просто иллюстрация возможности передачи двух (и более) строк по конвейеру на вход «diskpart.exe».
Ежели сделаете на «отлопаченном» проверенный рабочий вариант — поместите его в тему.
m0nkrus, у меня и одного-то нет . Я потому и писал — «не проверялось» »
Дык, у меня тоже нет. Для проверки я просто меняю код "\*$" на "\ $" и в качестве подопытных выступают MBR-разделы.
Ежели сделаете на «отлопаченном» проверенный рабочий вариант — поместите его в тему. »
Пока, на мой взгляд, оптимальный рабочий вариант, это тот, что на основе моего сделал Ксеноинженер.
Iska, хотя можно тоже кое-что и из ваших наработок позаимствовать, немного оптимизировав:
@ECHO OFF
CD /d %~dp0
FOR /f "tokens=2" %%i IN ('ECHO LIST DISK ^| DISKPART ^| FINDSTR /r /c:"\*$"') DO (>> diskpart.txt (ECHO select disk %%i && ECHO detail disk))
DISKPART /s "diskpart.txt" | FINDSTR /e "Boot Загрузоч" > nul
IF ERRORLEVEL 1 (
ECHO Загрузочный том размещен на MBR-разделе
) ELSE (
ECHO Загрузочный том размещен на GPT-разделе
)
PAUSE
Только не знаю, можно ли считать замену конструкции:
ECHO select disk %%i >> diskpart.txt && ECHO detail disk >> diskpart.txt
... на эту:
(>> diskpart.txt (ECHO select disk %%i && ECHO detail disk))
...оптимизацией. Если бы команд на каждом витке цикла было больше, то да, это бы подсократило код, но всего с двумя элементами особой разницы нет.
можно ли считать »
m0nkrus, если рассуждать теоретически, при большом количестве «echo» — можно: насколько я понимаю (замерял, но не проверял, например, в отладчике), при группировке вывода:
> Out.txt ( echo …
echo …
…
echo …)
открытие/закрытие файла происходит один раз в отличие от типичного:
echo …> Out.txt
echo …>> Out.txt
…
echo …>> Out.txt
0001.cmd
@echo off
setlocal enableextensions enabledelayedexpansion
echo %time%
>"%~n0.txt" (
for /l %%i in (1, 1, 10000) do (
echo %%i
)
)
echo %time%
endlocal
exit /b 0
0002.cmd
@echo off
setlocal enableextensions enabledelayedexpansion
echo %time%
for /l %%i in (1, 1, 10000) do (
>>"%~n0.txt" echo %%i
)
echo %time%
endlocal
exit /b 0
Результат:
E:\Песочница\0244>0001.cmd
14:10:02.20
14:10:02.56
E:\Песочница\0244>0002.cmd
14:10:05.06
14:10:14.06
Iska, согласен. Но, как я уже говорил, это становится сколько-нибудь критичным при много большем количестве вносимых строк.
@echo off
setlocal enableextensions enabledelayedexpansion
cd /d %~dp0
<nul set /p sVar=Загрузочный том размещен на
for /f "tokens=2" %%i in (
'echo list disk ^| diskpart.exe ^| findstr.exe /r /c:"\*$"'
) do set sDisk=%%i
if defined sDisk (
(
echo select disk !sDisk!
echo detail disk
) | diskpart.exe | findstr.exe /e "Boot Загрузоч" >nul && echo GPT-разделе || echo MBR-разделе
) else echo MBR-разделе
endlocal
exit /b 0
Как это будет работать при множественных GPT?
Всё равно мне не нравится такой путь.
Как это будет работать при множественных GPT? »
Хреново будет работать. Переменная sDisk по окончании цикла будет иметь инфу только о последнем GPT-диске из всего списка найденных. Тут массив нужен, а не переменная. Мы его и создаем во внешнем файле. Можно попытаться как-то воспользоваться идеей массива из этого топика: http://forum.oszone.net/post-1886306.html Там, кстати, и ваша благодарность прописана - вы его читали! Или, вот, альтернативная идея написания массива со стороннего сайта:
@echo off
setlocal enabledelayedexpansion
:: инициализировать 10 переменных вида arr.X случайными числами
for /l %%i in ( 0, 1, 9 ) do (
set /a arr.%%i=!RANDOM!
)
set arr
endlocalЯ вам уже говорил, временно замените "\*$" на "\ $" и прогоните таким образом скрипт на своих MBR-разделах. Скрипт станет принимать MBR за GPT и наоборот. Если на компе больше одного физического диска, и система стоит не на последнем, то это будет весьма наглядно.
Я вам уже говорил, временно замените "\*$" на "\ $" и прогоните таким образом скрипт на своих MBR-разделах. Скрипт станет принимать MBR за GPT и наоборот. Если на компе больше одного физического диска, и система стоит не на последнем, то это будет весьма наглядно. »
В том-то и дело:
1. Заменил «\*$» на «\ $».
2. Четыре физических диска, два из них в RAID. Логических, соответственно, три. Везде MBR.
3. Операционная система установлена на первом диске в его первом разделе.
4. Запустил код (http://forum.oszone.net/post-2140443.html#post2140443).
Получил следующее:
Загрузочный том размещен на MBR-разделе
А у Вас что получается при такой замене и на таком коде?
m0nkrus, я выше писал, что данный подход мне не нравится. Моя идея (реализацию которой я приводил выше на WSH и PoSH) — «танцевать вперёд», а не «пятится назад»: определить, какой раздел системный, получить его букву, по разделу получить содержащий его диск, и только потом смотреть, каков этот диск — MBR или GPT.
А у Вас что получается при такой замене и на таком коде? »
У меня при такой замене НА МОЕМ КОДЕ получается "Загрузочный том размещен на GPT-разделе". НА ВАШЕМ - то же самое, что и у вас - MBR. Как я уже говорил, переменная sDisk передает инфу только о последнем физическом диске в списке. Большинство людей подключают диск, предназначенный под систему, к порту с наименьшим номером. Ни вы, ни я не исключение. Посему на выдаче sDisk мы получаем не системный диск, а тот, который скорее всего используется под файлопомойку. Как результат, ключ "Boot Загрузоч" на нем не находится и скрипт считает, что системный диск размещен на разделе другого формата.
Моя идея (реализацию которой я приводил выше на WSH и PoSH) — «танцевать вперёд», а не «пятится назад»: определить, какой раздел системный, получить его букву, по разделу получить содержащий его диск, и только потом смотреть, каков этот диск — MBR или GPT. »
Объясню, почему я отдаю предпочтение CMD перед PowerShell: с языком CMD я достаточно знаком, чтобы понять, разобрать, найти ошибки и оптимизировать скрипт, в то время как с языком PowerShell я не знаком абсолютно. Вот вы (не в обиду) раз за разом наступаете на одни и те же грабли с переменной в CMD вместо массива - это я могу просечь и пресечь. А если вы мне предложите скрипт на WSH или PoSH с аналогичной или любой другой ошибкой, то я ее уже не смогу распознать! К тому же, я не знаю, корректно ли отработает ваш скрипт, запущенный из SetupComplete.cmd. Недавно, к примеру, столкнулся с тем, что скрипт, помещенный в аналогичный установочный файл oobe.cmd не воспринимает путь "%~dp0" - пришлось городить сложную конструкцию, чтобы определить путь запуска... И как вы себе представляете, что я буду вылавливать подобные проблемы без знания языка и не имея GPT-раздела под рукой? В остальном, согласен, что «танцевать вперёд» - более предпочтительный метод, на реализацию которого, по логике, должно затрачиваться куда меньше ресурсов.
m0nkrus, вот потому я и предлагаю другой путь — от буквы системного раздела к дисковому устройству (насчёт порта с наименьшим номером — немало раз видел иное: как недосборщику в голову взбредёт — так и будет; в любом случае, обоснованием корректности алгоритма сие не должно служить).
вот потому я и предлагаю другой путь — от буквы системного раздела к дисковому устройству »
Без проблем. Предложите его в CMD-формате и я с удовольствием им воспользуюсь. Если вы не заметили, то топик имеет пометку "CMD/BAT", а отнюдь не "PowerShell" или "Любой язык".
насчёт порта с наименьшим номером — немало раз видел иное: как недосборщику в голову взбредёт — так и будет; в любом случае, обоснованием корректности алгоритма сие не должно служить »
А кто обосновывает этим корректность алгоритма? Мой алгоритм (http://forum.oszone.net/post-2140405.html#post2140405) работает без привязки к тому, каким по счету идет системный GPT-раздел. А вот предложенный вами алгоритм (http://forum.oszone.net/post-2140443.html#post2140443) может сработать только либо в случае наличия всего одного GPT-раздела, либо если система при наличии нескольких таких разделов, находится на последнем в очереди GPT-диске.
Вас уже куда-то не туда заносит, вам не кажется? Уже какие-то наезды непонятные пошли. Если вы не в состоянии понять, почему вариант с массивом работает, а с переменной нет, или почему я не хочу использовать PowerShell-скрипт при наличии альтернативы в виде CMD-скрипта, то это не повод на меня наскакивать.
Мой алгоритм (http://www.oszone.net/go.php?url=http://forum.oszone.net/post-2140405.html#post2140405)…»
Мы столько наплодили, что по предыдущему Вашему сообщению:
У меня при такой замене НА МОЕМ КОДЕ »
мне было не совсем ясно, о каком коде именно идёт речь. Теперь понятно.
…работает без привязки к тому, каким по счету идет системный GPT-раздел. А вот предложенный вами алгоритм (http://www.oszone.net/go.php?url=http://forum.oszone.net/post-2140443.html#post2140443) может сработать только либо в случае наличия всего одного GPT-раздела, либо если система при наличии нескольких таких разделов, находится на последнем в очереди GPT-диске. »
Принимается.
Вас уже куда-то не туда заносит, вам не кажется? Уже какие-то наезды непонятные пошли. Если вы не в состоянии понять, почему вариант с массивом работает, а с переменной нет, или почему я не хочу использовать PowerShell-скрипт при наличии альтернативы в виде CMD-скрипта, то это не повод на меня наскакивать. »
Вам почудилось. Не обижайтесь и не воспринимайте сие в таком ракурсе. Подобного не было. Мне просто тоже было интересно разобраться. Разобрался (см. ниже).
Ваш код (http://www.oszone.net/go.php?url=http://forum.oszone.net/post-2140405.html#post2140405) у меня не работал. И при использовании «обратки» (смена «\*$» на «\ $») — тоже (кстати, и мой, сделанный по Вашему коду, в этой части — тоже не работал). Суть оказалась в том, что «diskpart.exe», идущий в комплекте с Windows XP, делает при перенаправлении вывод строк в формате Unix — не «CtLf», а только «Lf». «findstr.exe», идущий в комплекте с той же ОС, сопоставляет что параметр «/e», что символ «$» в регулярке «/r /c:"$"» только с «CrLf», но не сопоставляет с «Lf». Посему, при использовании параметра или «$», под Windows XP «findstr.exe» находит в выводе «diskpart.exe» одну b исключительно одну подходящую строку — завершающую:
DISKPART>
да и то лишь потому, что в конце её и вовсе нет никаких символов конца строки.
мне было не совсем ясно, о каком коде именно идёт речь. »
Что этот (http://forum.oszone.net/post-2139627.html#post2139627) вариант, что этот (http://forum.oszone.net/post-2140299.html#post2140299), что этот (http://forum.oszone.net/post-2140405.html#post2140405) с точки зрения отсутствия привязки к тому, каким по счету идет системный GPT-раздел, работают идентично.
m0nkrus, ну, так мне до этого нужно было ещё «дойти» ;).
На загрузочных GPT-дисках обязательно присутствует EFI в качестве 1-го системного раздела и MSR для 2-го. Информация об этом дается командой list partition. Поэтому принадлежность диска к GPT легко определить по типам раздела на диске.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.