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.