¿Cómo saber si / dev / sdX es un USB o HDD conectado?


23

¿Cómo puedo saber si es un disco duro local o una llave USB? Prefiero una forma de hacerlo sin privilegios de root./dev/sdX

OK, udevadmayudó mucho:

Para HDD local:

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

Para llave USB:

udevadm info --query=all --name=sdc | grep ID_BUS
E: ID_BUS=usb

Respuestas:


15

Hay algunas formas de saber sin privilegios de root, muchas de ellas difíciles / hacky:

Utilizando /dev/disk/by-id:

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

Si esto responde con algo así /dev/disk/by-id/usb-blah-blah-blah, entonces es un disco USB. Otros prefijos incluyen ata, dm, memstick, scsi, etc.

El uso /dev/disk/by-pathno es significativamente diferente:

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

Obtendrás algo como /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0. Esto muestra la ruta del dispositivo que conduce al disco. En este caso, una ruta aproximada es PCI → USB → disco. (tenga en cuenta el -usb-).

Usando udev (ejecuto Debian. Mi udevadmestá en el /sbinque no está en mi $PATH- el tuyo podría estar en otro lugar, dentro o fuera de tu $PATH):

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

Obtendrá el tipo de bus en el que se encuentra el dispositivo. Elimine la | grep ID_BUSlista completa de información (es posible que deba agregarla |less).

Si ha lshwinstalado, la respuesta de Huygens también puede funcionar:

lshw -class disk -class storage | less

Y mire a través de la salida de su disco. En less, pruebe /sdX y mire las bus infolíneas anteriores, la primera solo dirá scsi@…, pero la otra varias líneas antes será más esclarecedora. Sin embargo, realmente debería ejecutar esto como superusuario, por lo que puede no ser adecuado. (síntomas: en la computadora portátil lo probé, enumeraba el disco SATA pero no el USB, ejecutándose con sudoambos listados)

También hay otros, más o menos directos que estos.


¿Hay formas de distinguir una unidad SATA interna frente a una unidad SATA externa conectada esatap?
CMCDragonkai

10

Conozco una solución, pero, lamentablemente, requiere privilegio de root. De todos modos, aún puede resultarle útil:

sudo lshw -class disk -class storage

Para cada dispositivo, imprimirá el nombre lógico (por ejemplo, /dev/sda) y la información del bus, que en el caso de un dispositivo USB sería algo así como 'usb @ 1: 2'.

Salida de muestra:

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

Podrías usar lsblk:

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

donde -do --nodepssignifica no imprimir esclavos y / -o name,trano --output name,tranlista de medios solo el nombre del dispositivo y el tipo de transporte del dispositivo. Agregue rma la lista de columnas de salida para ver qué dispositivos son extraíbles ( 1si true):

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

Estaba buscando esto en las respuestas
Eduard Florinescu

4

Esto no necesita privilegios de root (pero muchos de estos comandos usan y dependen de bashisms, por lo que no funcionarán en todos los shells compatibles con POSIX):

Hay una forma rápida de preguntar 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

El archivo realmente interesante es capability. En mi Debian, tengo un genhd.harchivo, así que:

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

En absoluto, solo para saber si la bandera removableestá activada:

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

asi que

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

funciona probando si el capabilityvalor (que es 52 en mi sdaejemplo anterior) tiene el 1conjunto de bits (es decir, si es un número impar).

Pero Linux muestra todos los indicadores /sys, por lo que pedirlos /sys/block/sdX/removablees mucho más simple. ;-)

Por lo tanto, podría ser una llave USB removable, pero como hay muchos dispositivos extraíbles , preferiría asegurarme de que el tamaño del medio sea mayor que 0 (como una bandeja de CD-ROM descargada, para muestra) y que el dispositivo no esté en uso: al mirar eso sdX/trace/enableno está enlazado:

Nota: Todo esto está bien probado en bash v4.2 +.

En , puedes usar esta forma muy rápida y 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

En mi sistema, hay 4 llaves USB, pero una de ellas ( sde) ya está montada, por lo que la salida del comando anterior:

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

Mi guión:

Escribí una pequeña función para instalar Debian Live actualizado.

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

# La primera parte solo muestra el tamaño legible por humanos. La función comienza allí.

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
}

Esto asigna la respuesta, como una matriz , a la variable dada como primer argumento o variable $REPLY:

chooseFreeUsbKey stick

echo "$stick"
sdf

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

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

(El último campo puede contener espacios).


Gracias a @StephaneChazelas por hacer que la primera parte de mi respuesta sea más legible.
F. Hauri

1
(1) ¿Por qué tienes llaves anidadas? Qué quiere decir …,device/{model,type,vendor,uevent}? (2) ¿Puede explicar sus comandos GENHD y sus comandos "trace / enable"? (3) Su [ $(( $(< $file ) & 1 )) -ne 0 ]prueba se puede simplificar (acortar) a (( $(< $file ) & 1 )).
G-Man dice 'Restablecer a Monica'

@ G-Man (1) Sí, ¡+1 por esto! No entiendo cómo se introdujo este tipo. (2) El archivo de encabezado del disco duro genérico debe estar presente en /usr/src/*/include/linux. Tratar sed -ne 's/#define.*GENHD_FL_\([A-Z0-9_]*\)[ \t]*\([0-9]*\) \?.*$/GENHD_FLAGS[\2]="\1"/p;' /usr/src/*/include/linux/genhd.h. (3) Sí
F. Hauri

0

Sugiero simplemente usar hdparmo lshw(que puede necesitar instalar), y usar sudopara ejecutarlo como root.

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

todos deberían darle información.


hdparm en un disco virtual:hdparm -i /dev/sda /dev/sda: HDIO_DRIVE_CMD(identify) failed: Invalid exchange HDIO_GET_IDENTITY failed: Invalid argument
Tim

Bueno, dije que debería y funciona aquí con discos virtuales.
EightBitTony

0

Acabo de leer el valor de /sys/block/sdX/removable.

Por ejemplo:

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

/dev/sdc es una llave USB (podría ser una tarjeta SD o cualquier otro medio extraíble).


Esto duplica la información en la respuesta de F. Hauri y no agrega contenido nuevo. No publique una respuesta a menos que pueda agregar nuevos aspectos que no se encuentran en las respuestas existentes.
G-Man dice 'Restablece a Mónica'

0

dmesg es el método más fácil:

dmesg | grep sd X

( siendo el nombre de su dispositivo, por ejemplo )sdXsda

Desde el comando anterior, verá lo siguiente:

  • Disco SCSI adjunto (disco duro)
  • Disco extraíble SCSI adjunto (medios extraíbles; como una unidad flash USB)

dmesglee búfer de mensajes circular del núcleo por lo que esta solución sólo funciona relativamente poco tiempo después de un reinicio
roaima

0

Puede usar los siguientes comandos para obtener nodos de dispositivos SD, USB y 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) No es obvio para mí cómo esto responde a la pregunta, que es, "Para cualquier particular /dev/sdX, ¿cómo puedo saber si es un HDD local o una llave USB?" determinación. (2) Preferimos respuestas que dan comandos y las explicamos sobre respuestas que solo proporcionan comandos. Por favor explique lo que está haciendo. Por favor no responda en los comentarios; edite su respuesta para que sea más clara y completa. … (Continúa)
G-Man dice 'Restablecer a Monica'

(Cont.) ... (3)  awkes una herramienta muy poderosa. Muchos principiantes publican respuestas que hacen grepy canalizan su salida awk. Esto rara vez es necesario; awkpuede hacer coincidencia de patrones y puede seleccionar la entrada deseada sin ayuda de grep. Tiene una canalización de dos grepcomandos, entubados awk, y luego un segundo awk comando. Esto se puede simplificar enormemente; por favor, inténtalo. (4) Además, para mayor claridad, es posible que desee cambiar `…`a $(…): vea esto , esto y esto .
G-Man dice 'Restablecer a Monica'

0

Soy vago, inxi me dice esto fácilmente:

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

Creo que también me dice si es FireWire y tal vez otro tipo, pero tendría que comprobarlo dos veces, no he usado esos tipos en mucho tiempo.

También me dice que use -p si las particiones son remotas, como los montajes samba o nfs.


-1

Después de enchufar el dispositivo USB, ejecute dmesgen una ventana de consola. Se le proporcionarán algunos consejos.

Por ejemplo, dirá algo parecido a "Dispositivo conectado, almacenamiento masivo / dev / sdd".


2
Proporcione más información / aclaraciones para que su respuesta sea útil.
George M

2
¿Qué tal no ser insultante al responder una pregunta?
Shadur
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.