Jak sprawdzić, czy / dev / sdX jest podłączonym dyskiem USB lub HDD?


23

Skąd mam wiedzieć, czy jest to lokalny dysk twardy lub klucz USB? Wolę sposób na zrobienie tego bez uprawnień roota./dev/sdX

OK, bardzo udevadmpomogłem:

W przypadku lokalnego dysku twardego:

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

W przypadku klucza USB:

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

Odpowiedzi:


15

Istnieje kilka sposobów, aby powiedzieć bez uprawnień roota, wiele z nich jest trudnych / zhackowanych:

Używanie /dev/disk/by-id:

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

Jeśli to odpowiada czymś takim /dev/disk/by-id/usb-blah-blah-blah, to jest to dysk USB. Inne prefiksy obejmują ata, dm, memstick, scsi, itd.

Używanie /dev/disk/by-pathnie różni się znacząco:

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

Dostaniesz coś takiego /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0. Pokazuje ścieżkę urządzenia prowadzącą do dysku. W tym przypadku szorstką ścieżką jest PCI → USB → dysk. (zwróć uwagę na -usb-).

Korzystanie udev (uruchomić Debiana My. udevadmW /sbinktórych nie ma na moich $PATH- twój może być gdzie indziej, lub wyłączyć $PATH):

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

Otrzymasz typ magistrali, na której urządzenie jest włączone. Usuń, aby | grep ID_BUSuzyskać pełną listę informacji (może być konieczne dodanie |less).

Jeśli masz lshwzainstalowany, odpowiedź Huygensa może również działać:

lshw -class disk -class storage | less

I przejrzyj dane wyjściowe swojego dysku. W lesswypróbuj /sdX i spójrz na poprzednie bus infowiersze - pierwszy powie tylko scsi@…, ale jeden kilka wierszy przed nim będzie bardziej pouczający. Jednak naprawdę powinieneś uruchomić to jako superużytkownik, więc może nie być odpowiednie. (objawy: na laptopie próbowałem, wymieniono dysk SATA, ale nie dysk USB - działający z sudowymienionymi obydwoma)

Są też inne, mniej lub bardziej bezpośrednie niż te.


Czy istnieją sposoby na odróżnienie wewnętrznego dysku SATA od zewnętrznego dysku SATA podłączonego esatap?
CMCDragonkai

10

Znam rozwiązanie, ale niestety wymaga ono uprawnień administratora. W każdym razie nadal może się przydać:

sudo lshw -class disk -class storage

Dla każdego urządzenia wypisze nazwę logiczną (np. /dev/sda) I informacje o magistrali, co w przypadku urządzenia USB byłoby czymś w rodzaju „usb @ 1: 2”.

Przykładowe dane wyjściowe:

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

Możesz użyć lsblk:

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

gdzie -dlub --nodepsoznacza, że ​​nie drukuje urządzeń podrzędnych i -o name,tranlub --output name,tranoznacza tylko nazwę urządzenia i typ transportu urządzenia. Dodaj rmdo listy kolumn wyjściowych, aby zobaczyć, które urządzenia można usunąć ( 1jeśli true):

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

Szukałem tego w odpowiedziach
Eduard Florinescu

4

Nie wymaga to uprawnień roota (ale wiele z tych poleceń używa i zależy od bashism, więc nie będą działać we wszystkich powłokach zgodnych z POSIX):

Istnieje szybki sposób, aby zapytać o :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

Naprawdę interesujący plik jest capability. Na moim Debianie mam genhd.hplik, więc:

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

W ogóle, tylko dla wiedzy, czy flaga removablejest ustawiona:

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

więc

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

działa poprzez sprawdzenie, czy capabilitywartość (w moim sdaprzykładzie powyżej 52 ) ma 1ustawiony bit (tj. czy jest to liczba nieparzysta).

Ale Linux renderuje wszystkie flagi /sys, więc proszenie /sys/block/sdX/removablejest o wiele prostsze! ;-)

Tak więc kluczem USB może być removable, ale ponieważ istnieje wiele urządzeń wymiennych , wolałbym upewnić się, że rozmiar nośnika jest większy niż 0 (jak na przykład niezaładowana taca CD-ROM) i że urządzenie nie jest w użyj: Podczas oglądania sdX/trace/enablenie jest to związane:

Nota: Wszystko to zostało dobrze przetestowane na bash v4.2 +.

W ramach możesz użyć tego bardzo szybkiego i wydajnego sposobu:

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

W moim systemie są 4 klucze USB, ale jeden z nich ( sde) jest już zamontowany, więc wynik poprzedniego polecenia:

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

Mój skrypt:

Jest trochę funkcji którą napisałem, aby zainstalować uaktualniony 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]}
}

# Pierwsza część renderuje tylko rozmiar czytelny dla człowieka. Funkcja zaczyna się tam.

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
}

To przypisuje odpowiedź, jako tablicę , do zmiennej podanej jako pierwszy argument lub do zmiennej $REPLY:

chooseFreeUsbKey stick

echo "$stick"
sdf

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

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

(Ostatnie pole może zawierać spacje.)


Dziękuję @StephaneChazelas za uczynienie pierwszej części mojej odpowiedzi bardziej czytelną.
F. Hauri

1
(1) Dlaczego zagnieżdżasz nawiasy klamrowe? Czy masz na myśli …,device/{model,type,vendor,uevent}? (2) Czy możesz wyjaśnić swoje polecenia GENHD i polecenia „śledzenie / włączanie”? (3) Twój [ $(( $(< $file ) & 1 )) -ne 0 ]test można uprościć (skrócić) do (( $(< $file ) & 1 )).
G-Man mówi „Przywróć Monikę”

@ G-Man (1) Tak, +1 za to! Nie rozumiem, w jaki sposób wprowadzono to tipo. (2) Ogólny plik nagłówka dysku twardego musi znajdować się w /usr/src/*/include/linux. Spróbować sed -ne 's/#define.*GENHD_FL_\([A-Z0-9_]*\)[ \t]*\([0-9]*\) \?.*$/GENHD_FLAGS[\2]="\1"/p;' /usr/src/*/include/linux/genhd.h. (3) Tak.
F. Hauri

0

Sugeruję po prostu użycie hdparmlub lshw(które może być konieczne do zainstalowania) i użycie go sudodo wykonania jako root.

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

wszyscy powinni dać ci informacje.


hdparm na wirtualnym dysku:hdparm -i /dev/sda /dev/sda: HDIO_DRIVE_CMD(identify) failed: Invalid exchange HDIO_GET_IDENTITY failed: Invalid argument
Tim

Cóż, powiedziałem, że powinienem i działa tutaj z dyskami wirtualnymi.
EightBitTony


0

dmesg jest najłatwiejszą metodą:

dmesg | grep sd X

( będący nazwą Twojego urządzenia, np. )sdXsda

Z powyższego polecenia zobaczysz:

  • Dołączony dysk SCSI (dysk twardy)
  • Dołączony dysk wymienny SCSI (nośnik wymienny; taki jak dysk flash USB)

dmesgodczytuje okrągły bufor komunikatów jądra, więc to rozwiązanie będzie działać stosunkowo niedawno po ponownym uruchomieniu
roaima

0

Możesz użyć poniższych poleceń, aby uzyskać węzły urządzeń SD, USB i 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) Nie jest dla mnie oczywiste, w jaki sposób odpowiada na pytanie, które brzmi: „W każdym razie /dev/sdX, skąd mam wiedzieć, czy jest to lokalny dysk twardy czy klucz USB?” Proszę wyjaśnić, w jaki sposób OP może użyć twoich poleceń, aby to zrobić determinacja. (2) Wolimy odpowiedzi, które wydają polecenia i wyjaśniają je, niż odpowiedzi, które zawierają tylko polecenia. Wyjaśnij, co robisz. Proszę nie odpowiadać w komentarzach; edytuj swoją odpowiedź, aby była jaśniejsza i bardziej kompletna. … (Ciąg dalszy)
G-Man mówi „Przywróć Monikę”

(Ciąg dalszy)… (3)  awkto bardzo potężne narzędzie. Wielu początkujących zamieszcza odpowiedzi, które wykonują a grepi potokują swoje wyniki awk. Jest to rzadko konieczne; awkPotrafi dopasować wzór i może wybrać żądane dane wejściowe bez pomocy grep. Masz potok dwóch greppoleceń, potokowany do awk, a następnie drugie awk polecenie. Można to znacznie uprościć; proszę spróbować. (4) Dla jasności możesz chcieć zmienić `…`na $(…)- zobacz to , to i to .
G-Man mówi „Przywróć Monikę”

0

Jestem leniwy, inxi mówi mi to łatwo:

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

Wierzę, że mówi mi to również, czy to firewire i może jeden inny typ, ale musiałbym dwukrotnie sprawdzić, czy od jakiegoś czasu nie używałem tego typu.

Mówi mi również o użyciu -p, jeśli partycje są zdalne, takie jak samba lub nfs.


-1

Po podłączeniu urządzenia USB uruchom dmesgw oknie konsoli. Otrzymasz kilka wskazówek.

Na przykład powie coś w stylu „Urządzenie podłączone, pamięć masowa / dev / sdd”.


2
Podaj więcej informacji / wyjaśnień, aby Twoja odpowiedź była przydatna.
George M,

2
Co powiesz na to, by nie obrażać się podczas odpowiadania na pytanie?
Shadur
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.