BASH: поиск раздела из вывода diskutil

1

Я пытаюсь найти выходные данные команды, в которой перечислены локальные диски, чтобы найти раздел с именем EFI на загрузочном жестком диске.

Я написал очень грязный oneliner, так как я не могу понять, как эффективно найти основной жесткий диск (предположительно всегда Macintosh HD), а затем выяснить, что такое раздел EFI на том же диске, а затем оттуда найти disk # s # IDENTIFIER для раздела EFI на жестком диске Macintosh.

Стандартный вывод из diskutil listчего-то вроде этого

$ diskutil list
/dev/disk0
#:                       TYPE NAME                    SIZE       IDENTIFIER
0:      GUID_partition_scheme                        *500.1 GB   disk0
1:                        EFI EFI                     209.7 MB   disk0s1
2:                  Apple_HFS Macintosh HD            499.1 GB   disk0s2
3:                 Apple_Boot Recovery HD             784.2 MB   disk0s3

/dev/disk1
#:                       TYPE NAME                    SIZE       IDENTIFIER
0:      GUID_partition_scheme                        *1.5 TB     disk1
1:                        EFI EFI                     209.7 MB   disk1s1
2:                  Apple_HFS Data                    1.5 TB     disk1s2

Итак, вот грязный лайнер, который я использовал. Есть ли лучший способ сделать это? 

diskutil mount $(diskutil list | grep -i 'Macintosh\ HD' | awk '{print $6}' | grep -i 'disk0s')

juliushibert
источник

Ответы:

0

Я бы предположил, что / dev / disk0 всегда является «основным» HDD, верно? Если нет, и вы действительно хотите найти раздел EFI на диске с именем «Macintosh HD», то ваш oneliner почти верен.

Для меня $ 6 возвращает «ГБ», и я также предполагаю, что раздел EFI всегда является первым из этого конкретного диска, поэтому попробуйте:

diskutil list | grep 'Macintosh HD' | awk '{print $(NF)}' | sed 's/s[0-9]/s1/'

или еще немного хитрости (для хорошей меры):

diskutil list | awk '/Macintosh HD/ { sub(/s[0-9]/, "s1", $(NF)); print $(NF) }'
madeddie
источник
0

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

mount | awk '/on \/ / {print $1}'

Кажется, я не могу найти способ обнаружить мой основной том, поскольку мои выходные данные не содержат их списка, я могу видеть только основное блочное устройство и некоторое описание содержимого:

/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *251.0 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:          Apple_CoreStorage                         250.1 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                  Apple_HFS Macintosh HD           *249.8 GB   disk1
                                 Logical Volume on disk0s2
                                 XXXXXXXX-XXXX-XXXX-XXXX-7C6C089FXXXX
                                 Unencrypted

В моем случае я могу легко использовать, awk '/Logical Volume/ {print $NF}'но более надежный скрипт примет версию Mac для проверки всех возможных случаев.

Кстати, я использую Yosemite 10.10.4 на MBP 15 "середина 2014 года.

Ярон
источник
0

Хорошо, это не завершено, но у меня закончилось время.

Итак, я использую команду df, потому что я знаю, что у нее будет точка монтирования в конце. Затем я добавляю его с косой чертой новой строки. А потом я хотел вырезать все после первого выхода из космоса. Но вырезание не работает прямо сейчас. Не знаю, что я делаю неправильно, и я должен начать работать для своей работы прямо сейчас, но, возможно, вы можете улучшить вырезку из функции bash. Извините, нет времени искать руководство, чтобы найти мою ошибку. Но мы почти на месте

Исправленный:

foo=$(df -h | grep -e ' /$'); loo=${foo%%" "*}; echo $loo

Теперь это работает. Попытайся :)

РЕДАКТИРОВАТЬ: О, я только что понял, что я использую lvg, поэтому disk0s [0-4] будет переведен на disk1. Итак, протестируйте его и скажите, правильно ли он показывает правильный диск, на котором вы не используете lvg.

РЕДАКТИРОВАТЬ 2: Все еще не работает для зашифрованной логической группы томов, но если вы можете проверить это без FileVault, он должен работать

foo=$(mount | grep -e ' / '); foo=${foo%%" "*}; diskutil list | grep "[0-99]:" | grep ${foo##"/dev/"} | grep EFI)

Это будет искать EFI на диске, на котором он смонтирован как root, поэтому обычно MacintoshHD

РЕДАКТИРОВАТЬ 3: Это действительно здорово, чтобы убить время на работе. Хорошо, я думаю, это должно дать вам правильный ответ. Это можно сделать даже в том случае, если FileVault зашифрован.

#!/bin/bash

maindrive=$(mount | grep -e " / ")
maindrive_exact=${maindrive%%" "*}
maindrive_reduced=${maindrive_exact##"/dev/"}

if [ "$(diskutil list | grep Unlocked)" = "" ]
        then
                diskline=$(diskutil list | grep "[0-99]:" | grep $maindrive_reduced | grep EFI)
                diskline_cut1=${diskline##*"B "}
                diskline_cut2=${diskline##*" "}
                echo "/dev/$diskline_cut2"

        else
                alldisk=$(diskutil list)
                alldisk_cut1=${alldisk##*${maindrive_reduced}}
                alldisk_cut2=${alldisk_cut1#*"Logical Volume on "}
                alldisk_cut3=${alldisk_cut2%%" "*}
                echo /dev/$alldisk_cut3
fi

Итак, это должно дать вам раздел EFI на том же жестком диске, что и ваша корневая папка MacintoshHD.

РЕДАКТИРОВАТЬ 4 (Надеюсь, окончательный вариант)

#!/bin/bash

maindrive=$(mount | grep -e " / ")
maindrive_exact=${maindrive%%" "*}
maindrive_reduced=${maindrive_exact##"/dev/"} 


function getdisknumber {
diskline=$(diskutil list | grep "[0-99]:" | grep $maindrive_reduced | grep EFI)
                diskline_cut1=${diskline##*"B "}
                diskline_cut2=${diskline##*" "}
                echo "/dev/$diskline_cut2"
}

if [ "$(diskutil list | grep Unlocked)" = "" ] 
    then 
        getdisknumber   
    else 
        alldisk=$(diskutil list)
        alldisk_cut=${alldisk#*${maindrive_reduced}}
        alldisk_cut=${alldisk_cut#*"Logical Volume on "}
        alldisk_cut=${alldisk_cut%%" "*}
        alldisk_cut=${alldisk_cut%s*}
        maindrive_reduced=$alldisk_cut
        getdisknumber
fi

И вот объяснение

Okay, as ask in the comment, the explanation what %%,%,##,# means. 
All those symbols cut out information of a string.
%%pattern cuts out the biggest pattern matching part to the right.
%pattern cuts out the smallest pattern matching part to the right.
##pattern cuts out the biggest pattern matching part to the left
#pattern cuts out the smallest pattern matching part to the left

Другая часть сценария теперь пытается найти правильный жесткий диск, когда сталкивается с зашифрованным томом, созданным FileVault. Затем функция обрезает этот жесткий диск до информации о диске на этом жестком диске, ища EFI в качестве ключевого слова.

Вот ссылка о сокращении строк в Баш строк Cutting

РЕДАКТИРОВАТЬ 5: Хорошо. Еще одна итерация этого скрипта. Очень, очень до основ.

#!/bin/bash

## Find the main hard drive

maindrive=$(mount | grep -e " / ")
maindrive=${maindrive#/dev/}
maindrive=${maindrive%%" "*}


## Checking for FileVault

if [ "" != "$(diskutil list /dev/disk1 | grep "Unlocked Encrypted")" ]
        then
                maindrive=$(diskutil list | grep "Logical Volume on")
                maindrive=${maindrive#*"Logical Volume on "}
                maindrive=${maindrive%s*}
fi


## Checking for EFI

EFI_DRIVE=$(diskutil list /dev/$maindrive | grep EFI)
EFI_DRIVE=${EFI_DRIVE##*" "}
echo "/dev/$EFI_DRIVE"

Просто чтобы быть полным, это мой список рассуждений:

/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *250.1 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:          Apple_CoreStorage                         249.2 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                  Apple_HFS Macintosh HD           *248.8 GB   disk1
                                 Logical Volume on disk0s2
                                 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
                                 Unlocked Encrypted

И это происходит, когда я запускаю скрипт:

Joes-MacBook-Pro:EFI_Script joe$ chmod +x EFI_Script
Joes-MacBook-Pro:EFI_Script joe$ ./EFI_Script
/dev/disk0s1
Joes-MacBook-Pro:EFI_Script joe$

Я думал о том, почему это не сработало для вас до сих пор. Так что, в принципе, если это тоже не сработает, мне нужно от вас две информации. Во-первых, мне нужно знать ваш вывод для команды 'mount'. Моя выглядит так:

Joes-MacBook-Pro:EFI_Script joe$ mount
/dev/disk1 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)

Как видите, это дает мне точку монтирования '/' на 'disk1'. Я просто предположил, что если FileVault выключен, он даст вам вашу точку монтирования на disk0. Но, возможно, я ошибаюсь, и у меня нет системы, в которой FileVault выключен. Таким образом, если ваша точка монтирования также находится на disk1, в то время как EFI находится на disk0, она должна возвращаться пустой или только с / dev /, так как это то, что я добавил вручную. С другой стороны, если я правильно помню, у вас также был раздел EFI на disk1.

В любом случае, во-вторых, мне нужно, чтобы вы запустили этот скрипт с помощью команды 'bash -x script', чтобы он показал, что он делает во время работы. Таким образом, мы могли видеть, что идет не так.

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

Во всяком случае, проверить это. Ура!

TheCommoner282
источник
Ух ты, TheCommoner282, ты на этот раз поехал в город. foo=$(df -h | grep -e ' /$'); loo=${foo%%" "*}; echo $looи `выдает неправильный идентификатор диска, foo=$(mount | grep -e ' / '); foo=${foo%%" "*}; diskutil list | grep "[0-99]:" | grep ${foo##"/dev/"} | grep EFI; echo $fooоба производят / dev / disk0s2, а не / dev / disk0s1. Завтра я проверю твой длинный сценарий. Из интереса вы можете объяснить, что делает ваше использование символов %% и ##, поскольку я не могу найти какую-либо документацию по ним в Интернете. Т.е. в $ {maindrive %% "" *}? Я стремлюсь учиться.
Юлиюсиберт
Я отредактирую объяснение в. Кроме того, я нашел ошибку в своем сценарии и
исправлю
Боже мой, ты прав. Я просто посмотрел на вторую строку. Это просто свалка. Я 'echo $ foo', который не изменяется на втором этапе. И предыдущий «список дисков», вероятно, окажется пустым. Ну, плохое начало. Но будем надеяться, что четвертая итерация
сработает
Извините, что я потратил некоторое время на то, чтобы проверить ваше последнее предложение @ TheCommoner282 К сожалению, скрипт просто выводит /dev/. Спасибо за объяснение по сокращению в BASH. Действительно хорошая информация, чтобы знать.
Юлиюсиберт
Как странно. Я предполагаю, что должна быть некоторая разница между нашими выводами Diskutil, которые я не учел. Я перепишу скрипт и попробую учесть. Также я постараюсь добавить использовать ваш вывод, который вы разместили в тестовых целях. У меня есть идея или два, как ограничить это меньшим количеством информации, что означает меньшее сокращение и, следовательно, меньше ошибок или возможностей. Вы можете ожидать эту новую версию до завтра. Я сделаю это сегодня вечером (по Европе, GMT + 1)
TheCommoner282