Як дізнатися, чи / dev / sdX - це підключений USB чи жорсткий диск?


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 - вихід NAME, TRAN, RM
NAME TRAN   RM
sda  sata    0
sdb  sata    0
sdd  usb     1

Я шукав це у відповідях
Едуард Флоринеску,

4

Для цього не потрібні привілеї root (але багато з цих команд використовують і залежать від башизмів, тому вони не працюватимуть у всіх сумісних з 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 (наприклад, незавантажений лоток для компакт-дисків для зразка) і щоб пристрій не знаходився в використання: Для перегляду, що 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- дуже потужний інструмент. Багато початківців публікують відповіді, які роблять a 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

Я вважаю, що це також підказує мені, чи це брандмауер та, можливо, ще один тип, але мені доведеться ще раз перевірити, чи не використовували ці типи певний час.

Він також повідомляє мені, що використовує -p, якщо розділи віддалені, як-от кріплення samba або nfs.


-1

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

Наприклад, він буде щось говорити в рядку "Підключений пристрій, масове зберігання / dev / sdd".


2
Будь ласка, надайте більше інформації / пояснень, щоб зробити вашу відповідь корисною.
Джордж М

2
Як щодо того, щоб не ображати, відповідаючи на запитання?
Шадур
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.