Como saber se / dev / sdX é um USB ou HDD conectado?

21

Como posso saber se /dev/sdX é um HDD local ou uma chave USB? Eu preferiria uma maneira de fazer isso sem privilégios de root.

OK, udevadm ajudou muito:

Para HDD local:

udevadm info --query=all --name=sdb | grep ID_BUS
E: ID_BUS=ata

Para chave USB:

udevadm info --query=all --name=sdc | grep ID_BUS
E: ID_BUS=usb
    
por daisy 06.06.2012 / 15:16

10 respostas

14

Existem algumas maneiras de dizer sem privilégios de root, muitos deles complicados / hacky:

Usando /dev/disk/by-id :

find /dev/disk/by-id/ -lname '*sdX'

Se isso responde com algo como /dev/disk/by-id/usb-blah-blah-blah , então é um disco USB. Outros prefixos incluem ata , dm , memstick , scsi , etc.

Usar /dev/disk/by-path não é significativamente diferente:

find /dev/disk/by-path/ -lname '*sdX'

Você receberá algo como /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0 . Isso mostra o caminho do dispositivo que leva ao disco. Nesse caso, um caminho difícil é PCI → USB → disco. (observe o -usb- ).

Usando o udev (eu corro Debian. Meu udevadm está em /sbin , que não está no meu $PATH - o seu pode estar em outro lugar, dentro ou fora do seu $PATH ):

/sbin/udevadm info --query=all --name=sdX | grep ID_BUS

Você obterá o tipo de barramento em que o dispositivo está. Remova o | grep ID_BUS da lista completa de informações (talvez seja necessário adicionar |less ).

Se você tiver lshw instalado, a resposta da Huygens maio também funcionará:

lshw -class disk -class storage | less

E examine a saída do seu disco. Em less , tente / sdX e observe as linhas anteriores, bus info - a primeira apenas dirá scsi@… , mas as várias linhas antes dela serão mais esclarecedoras. No entanto, você realmente deve executar isso como o superusuário, por isso pode não ser adequado. (sintomas: no laptop que eu tentei, ele listou o disco SATA, mas não o USB - executando com sudo listando ambos)

Há outros também, mais ou menos diretos que esses.

    
por 06.06.2012 / 15:50
10

Eu conheço uma solução, mas, infelizmente, requer privilégios de root. De qualquer forma, você ainda pode achar útil:

sudo lshw -class disk -class storage

Para cada dispositivo, será impresso o nome lógico (por exemplo, /dev/sda ) e informações de barramento, que no caso de um dispositivo USB seria algo como 'usb @ 1: 2'.

Exemplo de saída:

[...]
  *-storage
       description: SATA controller
       physical id: d
       bus info: pci@0000:00:0d.0
       configuration: driver=ahci latency=64
[...]
     *-disk:0
          description: ATA Disk
          physical id: 0
          bus info: scsi@2:0.0.0
          logical name: /dev/sda
[...]
  *-scsi
       physical id: 3
       bus info: usb@1:2
       configuration: driver=usb-storage
     *-disk
          description: SCSI Disk
          physical id: 0.0.0
          bus info: scsi@6:0.0.0
          logical name: /dev/sdc
[...]
    
por 06.06.2012 / 15:46
6

Você pode usar lsblk :

lsblk -do name,tran
NAME TRAN
sda  sata
sdb  sata
sdd  usb

onde -d ou --nodeps significa não imprimir escravos e -o name,tran ou --output name,tran significa listar apenas o nome do dispositivo e o tipo de transporte do dispositivo. Adicione rm à lista de colunas de saída para ver quais dispositivos são removíveis ( 1 if true ):

lsblk --nodeps --output NAME,TRAN,RM
NAME TRAN   RM
sda  sata    0
sdb  sata    0
sdd  usb     1
    
por 24.08.2015 / 13:44
4

Isso não precisa de privilégios de root (mas muitos desses comandos usam e dependem de bashisms, então eles não funcionarão em todos os shells compatíveis com POSIX):

Existe uma maneira rápida de perguntar sobre um sdX :

grep -H . /sys/block/sda/{capability,uevent,removable,device/{model,type,vendor,uevent}}
/sys/block/sda/capability:52
/sys/block/sda/uevent:MAJOR=8
/sys/block/sda/uevent:MINOR=0
/sys/block/sda/uevent:DEVNAME=sda
/sys/block/sda/uevent:DEVTYPE=disk
/sys/block/sda/removable:0
/sys/block/sda/device/model:WDC WD360GD-00FN
/sys/block/sda/device/type:0
/sys/block/sda/device/vendor:ATA     
/sys/block/sda/device/uevent:DEVTYPE=scsi_device
/sys/block/sda/device/uevent:DRIVER=sd
/sys/block/sda/device/uevent:MODALIAS=scsi:t-0x00

O arquivo interessante realmente é capability . No meu Debian, eu tenho um arquivo genhd.h , então:

eval $(sed -ne '
   s/#define.*GENHD_FL_\([A-Z0-9_]*\)[ \t]*\([0-9]*\) \?.*$/GENHD_FLAGS[]=""/p
  ' /usr/src/linux-headers-2.6.32-5-common-openvz/include/linux/genhd.h)
diskCapa=$(</sys/block/sda/capability)
for i in ${!GENHD_FLAGS[@]};do
    (( diskCapa & i )) && echo ${GENHD_FLAGS[i]}
  done
MEDIA_CHANGE_NOTIFY
UP
SUPPRESS_PARTITION_INFO

diskCapa=$(</sys/block/sdd/capability)
    for i in ${!GENHD_FLAGS[@]};do
    (( diskCapa & i )) && echo ${GENHD_FLAGS[i]}
  done
REMOVABLE
MEDIA_CHANGE_NOTIFY
UP
SUPPRESS_PARTITION_INFO

Em tudo, por saber apenas se o sinalizador removable está definido:

grep REMOVABL /usr/src/linux-headers-3.2.0-4-common/include/linux/genhd.h 
#define GENHD_FL_REMOVABLE                      1

então

for disk in sd{a,b,c,d,e,f,g,h} ; do
 (( $(< /sys/block/$disk/capability ) & 1 ))  &&  echo $disk is removable
done

funciona testando se o valor capability (que é 52 no meu exemplo sda , acima) tem o conjunto de bits 1 (ou seja, se é um número ímpar).

Mas o Linux renderiza todos os sinalizadores em /sys , portanto, pedir /sys/block/sdX/removable é muito mais simples! ; -)

Assim, uma chave USB pode ser removable , mas como há muitos dispositivos removíveis , eu preferiria garantir que o tamanho da mídia seja maior que 0 (como uma bandeja de CD-ROM descarregada, por exemplo) e que o dispositivo é não em uso: ao observar que sdX/trace/enable não está vinculado:

Nota: Tudo isso está bem testado no bash v4.2 +.

Em , você pode usar essa maneira muito rápida e eficiente:

for disk in /sys/block/* ; do
    [ -f "$disk/removable" ]    && [ $(<"$disk/removable") -gt 0 ]   &&
    [ -f "$disk/size" ]         && [ $(<"$disk/size") -gt 0 ]        &&
    [ -f "$disk/trace/enable" ] && [ -z "$(<"$disk/trace/enable")" ] &&
    echo "${disk##*/} $(($(<"$disk/size")/1953125))G $(<"$disk/device/model")"
  done

No meu sistema, existem 4 chaves USB, mas uma delas ( sde ) já está montada, então a saída do comando anterior:

sdd 8G Trans-It Drive
sdf 7G Storage Media
sdg 4G silicon-power

Meu script:

Há uma pequena função que escrevi para instalar o Debian Live atualizado .

#!/bin/bash

txtsize() {
    local _c=$1 _i=0 _a=(b K M G T P)
    while [ ${#_c} -gt 3 ] ; do
        ((_i++))
        _c=$((_c>>10))
      done
    _c=000$(( ( $1*1000 ) >> ( 10*_i ) ))
    ((_i+=${3:-0}))
    printf -v ${2:-REPLY} "%.2f%s" ${_c:0:${#_c}-3}.${_c:${#_c}-3} ${_a[_i]}
}

# A primeira parte renderiza apenas o tamanho legível por humanos. A função começa aí.

chooseFreeUsbKey() {
    local _lUdisk _lUsize _lUdialog=dialog # whiptail # gdialog
    local -A _lUdevices
    unset ${1:-REPLY}
    for _lUdisk in /sys/block/*; do
        [ -f $_lUdisk/removable ] && [ $(<$_lUdisk/removable) -gt 0 ] &&
        [ -f $_lUdisk/size ] && [ $(<$_lUdisk/size) -gt 0 ] &&
        txtsize $(<$_lUdisk/size)*512 _lUsize &&
        [ -f $_lUdisk/trace/enable ] && [ -z "$(<$_lUdisk/trace/enable)" ] &&
        _lUdevices[${_lUdisk##*/}]="$_lUsize $(<$_lUdisk/device/model)"
    done
    case ${#_lUdevices[@]} in
        0 ) ;; # echo Sorry no key found. ;;
        1 ) IFS=§ read -a ${1:-REPLY} \
            <<< "${!_lUdevices[@]}§${_lUdevices[@]%% *}§${_lUdevices[@]#* }";;
        * ) declare -a menu
           for _lUdisk in ${!_lUdevices[@]}; do
               menu+=($_lUdisk "${_lUdevices[$_lUdisk]}")
           done
           _lUdisk=$($_lUdialog --menu "Choose a USB stick" \
               $((LINES-3)) $((COLUMNS-3)) $((LINES-8)) \
               "${menu[@]}" 2>&1 >/dev/tty)
           IFS=§ read -a ${1:-REPLY} \
           <<< "$_lUdisk§${_lUdevices[$_lUdisk]%% *}§${_lUdevices[$_lUdisk]#* }"
    esac
}

Isso atribui a resposta, como uma matriz , à variável fornecida como o primeiro argumento ou à variável $REPLY :

chooseFreeUsbKey stick

echo "$stick"
sdf

echo "${stick[1]}"
7.26G

echo "${stick[2]}"
Storage Media

(O último campo pode conter espaços.)

    
por 05.01.2013 / 01:22
0

Sugiro usar apenas hdparm ou lshw (que talvez você precise instalar) e usar sudo para executá-lo como root.

sudo hdparm -I /dev/sda
sudo lshw -short -C disk
sudo lshw -class disk -class storage

todos devem lhe dar informações.

    
por 06.06.2012 / 15:45
0

Apenas leia o valor de /sys/block/sdX/removable .

Por exemplo:

$ cat /sys/block/sda/removable
0
$ cat /sys/block/sdc/removable
1

/dev/sdc é uma chave USB (pode ser um cartão SD ou qualquer outra mídia removível).

    
por 10.06.2015 / 15:07
0

dmesg é o método mais fácil:

dmesg | grep sdX

( sdX é o nome do seu dispositivo, por exemplo, sda )

Pelo comando acima, você verá o seguinte:

  • Disco SCSI conectado (disco rígido)
  • Disco removível SCSI conectado (mídia removível; como, unidade flash USB)
por 29.07.2015 / 22:18
0

Você pode usar os comandos abaixo para obter nós de dispositivos SD, USB e SATA.

usb_device="/dev/'ls -lR /dev/disk/by-id/  | grep ^l | grep 'usb' | awk '{print $NF}' | cut -d '/' -f 3 | awk 'NR == 1''"

sata_device="/dev/'ls -lR /dev/disk/by-id/ | grep ^l | grep 'ata' | awk '{print $NF}' | cut -d '/' -f 3 | awk 'NR == 1''"

sd_device="/dev/'ls -lR /dev/disk/by-id/   | grep ^l | grep 'mmc' | awk '{print $NF}' | cut -d '/' -f 3 | awk 'NR == 1''"
    
por 05.05.2017 / 16:29
0

Eu sou preguiçoso, inxi me diz isso facilmente:

inxi -D
Drives:    HDD Total Size: 1220.3GB (33.2% used)
           ID-1: /dev/sda model: ST380817AS size: 80.0GB
           ID-2: /dev/sdb model: WDC_WD1003FZEX size: 1000.2GB
           ID-3: USB /dev/sdc model: USB_Flash_Drive size: 140.0GB

Eu acredito que ele também me diz se é firewire e talvez um outro tipo, mas eu teria que checar novamente, não usei esses tipos há algum tempo.

Ele também me diz usando -p se partições são remotas, como samba ou nfs.

    
por 11.05.2017 / 08:21
-1

Depois de conectar o dispositivo USB, execute dmesg em uma janela do console. Você receberá algumas dicas.

Por exemplo, ele diz algo como "Dispositivo conectado, armazenamento em massa / dev / sdd".

    
por 06.06.2012 / 15:18