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


23

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

OK, udevadmajudou 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

Respostas:


15

Existem algumas maneiras de dizer sem privilégios de root, muitas delas complicadas / hacky:

Usando /dev/disk/by-id:

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

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

O uso /dev/disk/by-pathnão é significativamente diferente:

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

Você terá 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 aproximado é PCI → USB → disco. (observe o -usb-).

Usando o udev (eu executo o Debian. O meu udevadmé o /sbinque 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ê verá o tipo de barramento em que o dispositivo está. Remova o | grep ID_BUSpara obter a lista completa de informações (pode ser necessário adicionar |less).

Se você tem lshw instalou, a resposta da Huygens também pode funcionar:

lshw -class disk -class storage | less

E observe a saída do seu disco. Em less, tente/ sdX e observe as bus infolinhas anteriores - a primeira dirá apenas scsi@…, mas a linha várias antes de ser mais esclarecedora. No entanto, você realmente deve executar isso como superusuário, para que ele não seja adequado. (sintomas: no laptop que eu tentei, ele listou o disco SATA, mas não o disco USB - funcionando com os sudodois listados)

Também existem outros, mais ou menos diretos do que esses.


Existem maneiras de diferenciar uma unidade SATA interna versus uma unidade SATA externa conectada esatap?
— CMCDragonkai #

10

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, ele imprimirá o nome lógico (por exemplo, /dev/sda) e as informações do barramento, que no caso de um dispositivo USB seriam algo como 'usb @ 1: 2'.

Saída de amostra:

[...]
  *-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
[...]

8

Você poderia usar lsblk:

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

onde -dou --nodepsmeios não imprimem escravos e -o name,tranou --output name,tranmeios listam 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 ( 1se true):

lsblk --nodeps --output NAME, TRAN, RM
NAME TRAN   RM
sda  sata    0
sdb  sata    0
sdd  usb     1

Eu estava procurando isso nas respostas
— Eduard Florinescu 04/04

4

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

Existe uma maneira rápida de perguntar sobre :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 realmente interessante é capability. No meu Debian, eu tenho um genhd.harquivo, então:

eval $(sed -ne '
   s/#define.*GENHD_FL_\([A-Z0-9_]*\)[ \t]*\([0-9]*\) \?.*$/GENHD_FLAGS[\2]="\1"/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

De todo, apenas para saber se o sinalizador removableestá 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 capabilityvalor (que é 52 na minhasda exemplo acima) tem o 1conjunto de bits (ou seja, se é um número ímpar).

Mas o Linux renderiza todas as bandeiras /sys , portanto, pedir /sys/block/sdX/removableé muito mais simples! ;-)

Portanto, poderia ser uma chave USB removable, mas como existem 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 seja dentro use: Ao assistir que sdX/trace/enablenão está vinculado:

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

No , você pode usar esta 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; portanto, o comando anterior gera:

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 processa 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.)


Obrigado a @StephaneChazelas por tornar a primeira parte da minha resposta mais legível.
— F. Hauri 05/01

1
(1) Por que você aninha chaves? Você quer dizer …,device/{model,type,vendor,uevent}? (2) Você pode explicar seus comandos GENHD e seus comandos "trace / enable"? (3) Seu [ $(( $(< $file ) & 1 )) -ne 0 ]teste pode ser simplificado (reduzido) para (( $(< $file ) & 1 )).
— G-Man diz 'Reinstate Monica'

@ G-Man (1) Sim, +1 para isso! Não entendo como esse tipo foi introduzido. (2) O arquivo de cabeçalho do disco rígido genérico deve estar presente em /usr/src/*/include/linux. Tente sed -ne 's/#define.*GENHD_FL_\([A-Z0-9_]*\)[ \t]*\([0-9]*\) \?.*$/GENHD_FLAGS[\2]="\1"/p;' /usr/src/*/include/linux/genhd.h. (3) sim
— 11297 F. Hauri

0

Eu sugiro apenas usar hdparmor lshw(que você pode precisar instalar) e usar sudopara executá-lo como root.

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

todos devem fornecer informações.


hdparm em um disco virtual:hdparm -i /dev/sda /dev/sda: HDIO_DRIVE_CMD(identify) failed: Invalid exchange HDIO_GET_IDENTITY failed: Invalid argument
— Tim

Bem, eu disse que deveria e funciona aqui com discos virtuais.
— precisa

0

Basta ler 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).


Isso duplica as informações da resposta de F. Hauri e não adiciona novos conteúdos. Não poste uma resposta, a menos que você possa adicionar novos aspectos não encontrados em nenhuma resposta existente.
— G-Man diz 'Reinstate Monica'

0

dmesg é o método mais fácil:

dmesg grep sd X

( sendo o nome do seu dispositivo, por exemplo, )sdXsda

No comando acima, você verá o seguinte:

  • Disco SCSI conectado (disco rígido)
  • Disco removível SCSI anexado (mídia removível; como unidade flash USB)

dmesglê o buffer de mensagens circulares do kernel para que esta solução funcione apenas relativamente recentemente após uma reinicialização
— roaima

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'`"

1
(1) Não é óbvio para mim como isso responde à pergunta, que é: “Para qualquer particular /dev/sdX, como posso saber se é um HDD local ou uma chave USB?” Explique como o OP pode usar seus comandos para fazer isso. determinação. (2) Preferimos respostas que dão comandos e as explicamos sobre respostas que fornecem apenas comandos. Por favor, explique o que você está fazendo. Por favor, não responda nos comentários; edite sua resposta para torná-la mais clara e completa. ... (continua)
— G-Man diz 'Reinstate Monica'

(Continua)… (3)  awké uma ferramenta muito poderosa. Muitos iniciantes postam respostas que fazem grepae direcionam sua saída awk. Isso raramente é necessário; awkpode fazer a correspondência de padrões e selecionar a entrada desejada sem a ajuda de grep. Você tem um pipeline de dois grepcomandos, canalizados awke, em seguida, um segundo awk comando. Isso pode ser bastante simplificado; tente por favor. (4) Além disso, para maior clareza, convém mudar `…`para $(…)- veja isto , isto e isto .
— G-Man diz 'Reinstate Monica'

0

Sou preguiçoso, o 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

Acredito que também me diga se é firewire e talvez um outro tipo, mas eu teria que verificar novamente, não os utilizo há algum tempo.

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


-1

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

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


2
Forneça mais informações / esclarecimentos para tornar sua resposta útil.
— George M

2
Que tal não ser insultuoso ao responder uma pergunta?
— Shadur 8/06/12
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.