我正在尝试搜索列出本地驱动器的命令的输出,以在启动硬盘上找到名为 EFI 的分区。
我写了一个非常肮脏的单行代码,因为我似乎无法弄清楚如何有效地找到主硬盘(大概总是 Macintosh HD),然后找出同一驱动器上的 EFI 分区,然后从那里找到 Macintosh HD 驱动器上 EFI 分区的磁盘#s# IDENTIFIER。
标准输出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')
答案1
我假设 /dev/disk0 始终是“主”硬盘,对吗?如果不是,而您确实想在名为“Macintosh HD”的磁盘上找到 EFI 分区,那么您的一行代码几乎是正确的。
对我来说,$6 返回“GB”,并且我还假设 EFI 分区始终是该特定磁盘的第一个分区,因此请尝试:
diskutil list | grep 'Macintosh HD' | awk '{print $(NF)}' | sed 's/s[0-9]/s1/'
或者使用更多的 awk 技巧(为了更好的效果):
diskutil list | awk '/Macintosh HD/ { sub(/s[0-9]/, "s1", $(NF)); print $(NF) }'
答案2
您可以尝试使用以下命令检测主块设备:
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 版本来检查所有可能的情况。
顺便说一句,我在 2014 年中期 MBP 15" 上使用的是 Yosemite 10.10.4。
答案3
好吧,这还没有完成,但是我没有时间了。
因此,我使用 df 命令,因为我知道这将在末尾有挂载点。然后我用斜线换行符模式对其进行 grep。然后我想删除第一个空格符号后的所有内容。但是现在删除不起作用。我真的不知道我做错了什么,我现在必须开始工作,但也许你可以改进 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)
这将在以 root 身份安装的磁盘上查找 EFI,因此通常是 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
因此,这应该会为您提供与根文件夹 MacintoshHD 位于同一硬盘上的 EFI 分区。
编辑 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
脚本的 else 部分现在尝试在遇到 FileVault 创建的加密卷时找到正确的硬盘。然后,该函数将该硬盘细分为该硬盘上的磁盘信息,并寻找 EFI 作为关键字。
这是关于在 bash 中剪切字符串的链接 剪断琴弦
编辑 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/,因为这是我手动添加的。另一方面,如果我没记错的话,您在 disk1 上也有一个 EFI 分区。
无论如何,我需要的第二件事是使用命令“bash -x script”运行此脚本,以便它在运行时显示其执行的操作。这样,我们就可以看到哪里出了问题。
无论如何,我希望它能正常工作,我们不必费这么大劲。但如果不行,我们必须想出另一种方法来找到主硬盘。
无论如何,测试一下吧。干杯!