目标
可以读取磁盘号并执行挂载命令的简单单行程序是什么?
单行代码将执行相当于:
./mountEFI.command disk3
背景
user@mac ~ % diskutil 列表
回报
/dev/disk0 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *128.0 GB disk0
1: EFI NO NAME 104.9 MB disk0s1
2: Microsoft Reserved 16.8 MB disk0s2
3: Microsoft Basic Data NTFS 127.4 GB disk0s3
4: Windows Recovery 525.3 MB disk0s4
/dev/disk1 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *1.0 TB disk1
1: EFI EFI 209.7 MB disk1s1
2: Apple_APFS Container disk2 1000.0 GB disk1s2
/dev/disk2 (synthesized):
#: TYPE NAME SIZE IDENTIFIER
0: APFS Container Scheme - +1000.0 GB disk2
Physical Store disk1s2
1: APFS Volume LANCE - Data 60.7 GB disk2s1
2: APFS Volume LANCE 15.3 GB disk2s3
3: APFS Snapshot com.apple.os.update-... 15.3 GB disk2s3s1
4: APFS Volume Preboot 309.8 MB disk2s4
5: APFS Volume Recovery 620.4 MB disk2s5
6: APFS Volume VM 1.1 MB disk2s6
/dev/disk3 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *61.5 GB disk3
1: EFI EFI_USB 209.7 MB disk3s1
2: Apple_HFS Install macOS Monterey 61.2 GB disk3s2
所以:
diskutil list | grep '(external, physical)'
回报
/dev/disk3 (external, physical):
^ ^
6 10
目标是返回字符 6-10,磁盘3。
单行代码必须执行等效于:
./mountEFI.command disk3
可以读取磁盘号并执行挂载命令的简单单行程序是什么?
更新
diskutil list -plist external physical
回报
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AllDisks</key>
<array>
<string>disk3</string>
<string>disk3s1</string>
<string>disk3s2</string>
</array>
<key>AllDisksAndPartitions</key>
<array>
<dict>
<key>Content</key>
<string>GUID_partition_scheme</string>
<key>DeviceIdentifier</key>
<string>disk3</string>
<key>OSInternal</key>
<false/>
<key>Partitions</key>
<array>
<dict>
<key>Content</key>
<string>EFI</string>
<key>DeviceIdentifier</key>
<string>disk3s1</string>
<key>DiskUUID</key>
<string>5F5C5E00-71B1-4259-B062-95683183898B</string>
<key>Size</key>
<integer>209715200</integer>
<key>VolumeName</key>
<string>EFI_USB</string>
<key>VolumeUUID</key>
<string>0E239BC6-F960-3107-89CF-1C97F78BB46B</string>
</dict>
<dict>
<key>Content</key>
<string>Apple_HFS</string>
<key>DeviceIdentifier</key>
<string>disk3s2</string>
<key>DiskUUID</key>
<string>059700E8-2B72-4669-9030-7C783AA398FB</string>
<key>MountPoint</key>
<string>/Volumes/Install macOS Monterey</string>
<key>Size</key>
<integer>61186465792</integer>
<key>VolumeName</key>
<string>Install macOS Monterey</string>
<key>VolumeUUID</key>
<string>14B0CA5F-27B4-31E3-8096-9235338AFBBD</string>
</dict>
</array>
<key>Size</key>
<integer>61530439680</integer>
</dict>
</array>
<key>VolumesFromDisks</key>
<array>
<string>Install macOS Monterey</string>
</array>
<key>WholeDisks</key>
<array>
<string>disk3</string>
</array>
</dict>
</plist>
答案1
听起来你更想要"/dev/"
和之间的部分" (external, physical):"
,所以:
diskutil list | sed -n 's|^/dev/\(.*\) (external, physical)$|\1|p'
cut
可以从某些输入的每一行返回一定范围的字节,但该输入必须通过其标准输入传递,而不是作为参数传递,因此:
diskutil list | grep '(external, physical)' | cut -b 6-10
disk10
但对于名称不遵循该模式的及以上或块设备,该方法将失败。
您可以将去掉前导空格的每一行(假设它不包含撇号、双引号或反斜杠)作为单独调用./mountEFI.command
using的一个参数xargs
:
diskutil list |
sed -n 's|^/dev/\(.*\) (external, physical)$|\1|p' |
xargs -I DISK ./mountEFI.command DISK
答案2
我会使用 awk:
(我没有 Mac,所以我使用包含示例输出的文本文件作为 awk 的输入。与 的工作方式相同diskutil list | awk ...
)
$ awk -F'[/ ]' '/external, physical/ { print $3 }' /tmp/diskutil.list
disk3
使用/
和(空格)作为字段分隔符,此 awk 脚本仅在与“external,physical”匹配的任何行上打印第三个字段 ( )。
$3
不打印不匹配的输入行。
第一个字段是第一个之前的空字符串/
,第二个字段是第一个和第二个/
( dev
) 之间的任何内容,第三个字段是第二个/
和第一个空格字符 ( disk3
) 之间的任何内容。
./mountEFI.command
要对每个磁盘执行,您可以使用xargs
:
diskutil list awk -F'[/ ]' '/external, physical/ { print $3 }' | xargs -L 1 ./mountEFI.command
告诉-L 1
xargs 运行./mountEFI.command
每行一次如果 awk 有多于一行的输出。
如果没有-L 1
,xargs
将尝试运行该命令一次(或者如果有数千行,则尽可能少运行一次,具体取决于系统上的 ARG_MAX...不知道它在 Mac 上是什么,但在 Linux 上大约有 200 万个字符,所以“很多”。)使用尽可能多的参数(例如,如果disk0和disk1匹配模式,xargs将运行),除非可以循环多个参数,./mountEFI.command disk0 disk1
否则它将不起作用。./mountEFI.command