Как узнать, является ли / dev / sdX подключенным USB или HDD?


23

Как я могу узнать, является ли локальный жесткий диск или USB-ключ? Я бы предпочел способ сделать это без прав root./dev/sdX

ОК, очень udevadmпомогло:

Для локального жесткого диска:

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

Для USB-ключа:

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

Ответы:


15

Есть несколько способов сказать без привилегий root, многие из них хитрые / хакерские:

Использование /dev/disk/by-id:

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

Если это отвечает чем-то вроде /dev/disk/by-id/usb-blah-blah-blah, то это USB-диск. Другие префиксов ata, dm, memstick, scsiи т.д.

Использование /dev/disk/by-pathсущественно не отличается:

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

Вы получите что-то вроде /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0. Это показывает путь устройства, ведущий к диску. В этом случае грубым путем является PCI → USB → диск. (обратите внимание -usb-).

Использование udev (я запускаю Debian. Мой udevadmнаходится в том, /sbinчто не на моем $PATH- ваш может быть в другом месте, на вашем или без $PATH):

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

Вы получите тип шины, на которой включено устройство. Удалите | grep ID_BUSдля полного списка информации (может потребоваться добавить |less).

Если вы lshwустановили, ответ Гюйгенс также может работать:

lshw -class disk -class storage | less

И просмотрите вывод для вашего диска. В less, попробуйте /sdX и посмотрите на предыдущие bus infoстроки - первая просто скажет scsi@…, а та, что за несколько строк до нее, будет более поучительной. Тем не менее, вы действительно должны запустить это как суперпользователь, так что он может не подойти. (Симптомы: на ноутбуке, который я пробовал, был указан диск SATA, но не USB-диск - работает с sudoобоими списками)

Есть и другие, более или менее прямые, чем эти.


Есть ли способы отличить внутренний диск SATA от внешнего диска SATA, подключенного поверх esatap?
CMCDragonkai

10

Я знаю решение, но, к сожалению, оно требует прав суперпользователя. В любом случае, вы все равно можете найти это полезным:

sudo lshw -class disk -class storage

Для каждого устройства будет напечатано логическое имя (например, /dev/sda) и информация о шине, которая в случае устройства USB будет выглядеть примерно так: «usb @ 1: 2».

Пример вывода:

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

Вы можете использовать lsblk:

lsblk - имя, тран
NAME TRAN
sda  sata
sdb  sata
sdd  usb

где -dили --nodepsозначает, что не печатаются ведомые устройства, и -o name,tranили --output name,tranозначает, что в списке указано только имя устройства и тип транспорта устройства. Добавьте rmв список выходных столбцов, чтобы увидеть, какие устройства являются съемными ( 1если true):

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

Я искал это в ответах
Эдуард Флоринеску

4

Для этого не нужны привилегии root (но многие из этих команд используют и зависят от bashisms, поэтому они не будут работать во всех POSIX-совместимых оболочках):

Есть быстрый способ спросить о :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

Действительно интересный файл capability. На моем Debian у меня есть genhd.hфайл, поэтому:

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

В общем, только для того, чтобы знать, установлен ли флаг removable:

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

так

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

работает, проверяя, имеет ли capabilityзначение (которое в моем sdaпримере выше 52 ) установленный 1бит (т. е. является ли оно нечетным числом).

Но Linux отображает все флаги /sys, так что просить /sys/block/sdX/removableнамного проще! ;-)

Таким образом , ключ USB может быть removable, но так как есть много съемных устройств, я бы предпочел , чтобы убедиться , что размер среды больше 0 (как незагруженном лоток CD-ROM, для образца) и что устройство находится не в использование: при просмотре sdX/trace/enableне привязано:

Примечание: все это хорошо протестировано на bash v4.2 +.

В вы можете использовать этот очень быстрый и эффективный способ:

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

В моей системе есть 4 USB-ключа, но один из них ( sde) уже смонтирован, поэтому вывод предыдущей команды:

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

Мой сценарий:

Я написал небольшую функцию для установки обновленного Debian Live.

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

# Первая часть отображает только читаемый размер. Функция начинается там.

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
}

Это присваивает ответ в виде массива переменной, заданной в качестве первого аргумента, или переменной $REPLY:

chooseFreeUsbKey stick

echo "$stick"
sdf

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

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

(Последнее поле может содержать пробелы.)


Спасибо @StephaneChazelas за то, что сделали первую часть моего ответа более читабельной.
Ф. Хаури

1
(1) Почему у вас есть вложенные фигурные скобки? Вы имеете в виду …,device/{model,type,vendor,uevent}? (2) Можете ли вы объяснить ваши команды GENHD и ваши команды «трассировки / включения»? (3) Ваш [ $(( $(< $file ) & 1 )) -ne 0 ]тест может быть упрощен (сокращен) до (( $(< $file ) & 1 )).
G-Man говорит: «Восстановите Монику»

@ G-Man (1) Да, +1 за это! Я не понимаю, как это типо было введено. (2) Общий файл заголовка жесткого диска должен присутствовать в /usr/src/*/include/linux. Попробуй sed -ne 's/#define.*GENHD_FL_\([A-Z0-9_]*\)[ \t]*\([0-9]*\) \?.*$/GENHD_FLAGS[\2]="\1"/p;' /usr/src/*/include/linux/genhd.h. (3) Да.
Ф. Хаури

0

Я предлагаю просто использовать hdparmили lshw(что вам может потребоваться установить) и использовать sudoдля запуска его от имени пользователя root.

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

все должны дать вам информацию.


hdparm на виртуальном диске:hdparm -i /dev/sda /dev/sda: HDIO_DRIVE_CMD(identify) failed: Invalid exchange HDIO_GET_IDENTITY failed: Invalid argument
Тим

Ну, я сказал, должен и он работает здесь с виртуальными дисками.
EightBitTony

0

Просто прочитайте стоимость /sys/block/sdX/removable.

Например:

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

/dev/sdc USB-ключ (это может быть SD-карта или любой другой съемный носитель).


Это дублирует информацию в ответе Ф. Хаури и не добавляет нового контента. Пожалуйста, не публикуйте ответ, если вы не можете добавить новые аспекты, которых нет ни в одном из существующих ответов.
G-Man говорит: «Восстанови Монику»

0

dmesg это самый простой метод:

Dmesg | grep sd X

( будучи именем вашего устройства, например, )sdXsda

Из приведенной выше команды вы увидите следующее:

  • Прикрепленный диск SCSI (жесткий диск)
  • Прикрепленный съемный диск SCSI (съемный носитель; например, USB-накопитель)

dmesgчитает буфер кольцевых сообщений ядра, так что это решение будет работать относительно недавно после перезагрузки
roaima

0

Вы можете использовать приведенные ниже команды для получения узлов устройств SD, USB и 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) Для меня не очевидно, как это отвечает на вопрос, а именно: « /dev/sdXКак я могу узнать, является ли это локальный жесткий диск или USB-ключ?». Пожалуйста, объясните, как ОП может использовать ваши команды, чтобы сделать это. определение. (2) Мы предпочитаем ответы, которые дают команды и объясняют их, а не ответы, которые предоставляют только команды. Пожалуйста, объясните, что вы делаете. Пожалуйста, не отвечайте в комментариях; отредактируйте свой ответ, чтобы сделать его более понятным и полным. … (Продолжение)
G-Man говорит «Восстановить Монику»

(Продолжение)… (3)  awkочень мощный инструмент. Многие новички публикуют ответы, которые делают grepи направляют свои результаты awk. Это редко необходимо; awkможет сделать сопоставление с образцом и может выбрать нужный ввод без помощи grep. У вас есть конвейер из двух grepкоманд, переданных по каналу awk, а затем вторая awk команда. Это может быть значительно упрощено; пожалуйста, попробуй. (4) Кроме того , для ясности, вы можете захотеть изменить `…`на $(…)- см это , это и это .
G-Man говорит: «Восстанови Монику»

0

Я ленивый, Инси говорит мне это легко:

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

Я считаю, что это также говорит мне, если это FireWire и, возможно, еще один тип, но я должен был бы перепроверить, не использовал эти типы в какое-то время.

Он также сообщает мне, используя -p, если разделы являются удаленными, например, samba или nfs mounts.


-1

После подключения USB-устройства запустите dmesgокно консоли. Вам будут предоставлены некоторые подсказки.

Например, он говорит что-то вроде «Устройство подключено, запоминающее устройство / dev / sdd».


2
Пожалуйста, предоставьте больше информации / разъяснений, чтобы ваш ответ был полезным.
Джордж М

2
Как насчет того, чтобы не оскорблять, отвечая на вопрос?
Шадур
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.