我正在编写一个 bash 脚本,并努力寻找一种方法来创建关联数组,该数组保存通过 USB 插入的每个安装的外部硬盘驱动器的一个密钥和一个属性。我这里使用的示例是关联数组,但它不是必须的。虽然我觉得这是最有道理的。是的,我正在使用 bash 4 来支持关联数组。
> /bin/bash --version
GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.3.0)
目前我正在循环中使用diskutil list
和作为子shell 。或者只是使用,和命令的混合通过管道解析一堆输出。至今无济于事。应该注意的是,这些苹果命令输出了我想丢弃的其他东西,例如蓝牙设备和我的本地硬盘驱动器。详情请参阅下文。system_profiler SPUSBDataType
for
sed
grep
awk
我想要的数组看起来像这样:myArray=([Name1]=/dev/disk3s2 [Name2]=/dev/disk4s2)
。我真的只需要名称和它的安装点。它的格式是灵活的。如果采用不同的格式,我可以稍后解析它。我只需要能够做一个简单的for i in "!${myArray[@]}; do echo "Name = ${i}"; echo "mount point = ${myArray[$i]}"; done
或类似的事情。
注意:在一天结束时,它会提示用户类似“您安装了 N 个外部硬盘驱动器,请选择您想要执行备份的一个”
按照此处的要求,我已经使用了两个主要命令(diskutil list
和system_profiler SPUSBDataType
)的示例输出,以尝试实现我的目标。尽管应该指出,我并不关心是否还有其他方法可以实现相同的预期目标。如果您知道其他有用的命令,请推荐。
> diskutil list
/dev/disk0 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *500.3 GB disk0
1: EFI EFI 209.7 MB disk0s1
2: Apple_CoreStorage Macintosh HD 499.4 GB disk0s2
3: Apple_Boot Recovery HD 650.0 MB disk0s3
/dev/disk1 (internal, virtual):
#: TYPE NAME SIZE IDENTIFIER
0: Apple_HFS Macintosh HD +499.1 GB disk1
Logical Volume on disk0s2
A0B29294-0031-40CB-8894-6F56545CCF3C
Unencrypted
/dev/disk3 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *2.0 TB disk3
1: EFI EFI 209.7 MB disk3s1
2: Apple_HFS Storage 2.0 TB disk3s2
和
> system_profiler SPUSBDataType
USB:
USB 3.0 Bus:
Host Controller Driver: AppleUSBXHCIWPT
PCI Device ID: 0x9cb1
PCI Revision ID: 0x0003
PCI Vendor ID: 0x8086
BUP Slim SL:
Product ID: 0xab26
Vendor ID: 0x0bc2 (Seagate LLC)
Version: 1.08
Serial Number: NA96KBJB
Speed: Up to 5 Gb/sec
Manufacturer: Seagate
Location ID: 0x14500000 / 3
Current Available (mA): 900
Current Required (mA): 896
Extra Operating Current (mA): 396
Media:
BUP Slim SL:
Capacity: 2 TB (2,000,398,933,504 bytes)
Removable Media: No
BSD Name: disk3
Logical Unit: 0
Partition Map Type: GPT (GUID Partition Table)
USB Interface: 0
Volumes:
EFI:
Capacity: 209.7 MB (209,715,200 bytes)
File System: MS-DOS FAT32
BSD Name: disk3s1
Content: EFI
Volume UUID: 0E239BC6-F960-3107-89CF-1C97F78BB46B
Storage:
Capacity: 2 TB (2,000,054,960,128 bytes)
Available: 1.3 TB (1,298,787,659,776 bytes)
Writable: Yes
File System: Journaled HFS+
BSD Name: disk3s2
Mount Point: /Volumes/Storage
Content: Apple_HFS
Volume UUID: E9786DAE-78A7-31B7-B939-8FCCE3C147AB
Bluetooth USB Host Controller:
Product ID: 0x8290
Vendor ID: 0x05ac (Apple Inc.)
Version: 1.46
Speed: Up to 12 Mb/sec
Manufacturer: Broadcom Corp.
Location ID: 0x14300000 / 2
Current Available (mA): 500
Current Required (mA): 0
Extra Operating Current (mA): 0
Built-In: Yes
diskutil list | tail -n +15
基本上会给我本地硬盘驱动器之后的所有内容。
我的另一个想法是我可以做一些for usb in $(system_profiler SPUSBDataType)
声明。但我无法找出正确的子 shell 命令来通过管道传输到sed
、grep
和awk
其他工具来通过空行或缩进进行解析。我很可能无法像这样一次性完成它。
答案1
我不确定这是否适合您,因为它仅检查外部驱动器而不一定是 USB 驱动器,但我相信它主要满足您的需要:
#! /usr/local/bin/bash -
IFS= mapfile -t DISKUTIL_LIST < <(diskutil list external)
declare -A myAssocArray
for line in "${DISKUTIL_LIST[@]}"; do
DISK_MOUNT=$(echo $line | awk '{print $1}')
if [[ "${#DISK_MOUNT}" -lt '3' ]]; then
:
else
ARRAY_INDEX=$(mount | grep "$DISK_MOUNT" | awk '{print $3}' | awk -F'/' '{print $NF}')
MOUNT_POINT=$(mount | grep "$DISK_MOUNT" | awk '{print $1}')
myAssocArray+=([${ARRAY_INDEX}]="$MOUNT_POINT")
fi
done
for disk in "${!myAssocArray[@]}"; do
echo -e "Name:\t\t${disk}\nMount Point:\t${myAssocArray[$disk]}"
done
我的示例输出(我目前只有一个外部):
{0} ➔ ./usb-drives.sh
Name: JBUTRYN
Mount Point: /dev/disk2s1