Crie uma matriz no script bash a partir de unidades externas USB montadas no macOS

1

Estou escrevendo um script bash e lutando para encontrar uma maneira de criar um array associativo que contenha uma chave e um atributo para cada disco rígido externo conectado conectado via USB. Meu exemplo usado aqui é um array associativo, mas não precisa ser. Embora eu ache que faz mais sentido. E sim, estou usando o bash 4 para o suporte à matriz associativa.

> /bin/bash --version
GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.3.0)

Atualmente, estou brincando com diskutil list e system_profiler SPUSBDataType como subshells em um loop for . Ou apenas analisando um grupo da saída por meio de pipes com uma mistura dos comandos sed , grep e awk . Até agora sem sucesso. Deve-se notar que esses comandos da Apple geram outras coisas que eu quero descartar, como dispositivos bluetooth e meu disco rígido local. Veja abaixo para detalhes.

Meu array desejado seria parecido com isto: myArray=([Name1]=/dev/disk3s2 [Name2]=/dev/disk4s2) . Eu realmente só preciso do nome e do ponto de montagem. O formato dele é flexível. Eu posso analisá-lo mais tarde, se em um formato diferente. Eu só preciso ser capaz de fazer um simples for i in "!${myArray[@]}; do echo "Name = ${i}"; echo "mount point = ${myArray[$i]}"; done ou algo similar.

Nota: no final do dia, ele irá pedir ao usuário algo como "Você tem um número N de discos rígidos externos montados, por favor, selecione qual deles você gostaria de fazer o backup para"

Como solicitado, aqui está o exemplo de saída dos dois principais comandos ( diskutil list e system_profiler SPUSBDataType ) que tenho usado para tentar atingir minha meta. Embora deva ser observado, não me importo se existem outras maneiras de alcançar o mesmo objetivo desejado. Se você souber de outros comandos úteis, por favor sugira.

> 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

e

> 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 me dará basicamente tudo depois do meu disco rígido local.

Outro pensamento que tive foi que eu poderia fazer algum tipo de declaração for usb in $(system_profiler SPUSBDataType) . Mas não consigo descobrir o comando subshell certo para canalizar para sed , grep , awk e outras ferramentas para analisar por linhas em branco ou recuo. É mais do que provável que eu não seja capaz de implementá-lo de forma tão simples.

    
por Byron Mansfield 25.09.2017 / 13:49

1 resposta

1

Não tenho certeza se isso funcionará para você ou não, já que está verificando apenas as unidades externas e não necessariamente as unidades USB, mas acredito que ele faz basicamente o que você precisa:

#! /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

Exemplo de saída para mim (só tenho um externo no momento):

{0} ➔ ./usb-drives.sh
Name:           JBUTRYN
Mount Point:    /dev/disk2s1
    
por 25.09.2017 / 14:25

Tags