จะทราบได้อย่างไรว่า / dev / sdX เป็น USB หรือ HDD ที่เชื่อมต่ออยู่


23

ฉันจะรู้ได้อย่างไรว่าHDD ในตัวหรือ USB สำคัญ ฉันต้องการวิธีการทำเช่นนี้โดยไม่มีสิทธิ์รูท/dev/sdX

ตกลงudevadmช่วยได้มาก:

สำหรับ HDD ในเครื่อง:

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

มีหลายวิธีที่จะบอกได้โดยไม่ต้องใช้สิทธิ์รูทส่วนใหญ่เป็นวิธีที่ยากลำบาก

การใช้/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ติดตั้งแล้วคำตอบของ Huygens อาจใช้งานได้:

lshw -class disk -class storage | less

และมองผ่านผลลัพธ์สำหรับดิสก์ของคุณ ในlessลอง/sdX แล้วดูbus infoบรรทัดก่อนหน้าบรรทัดแรกจะพูดscsi@…แต่หนึ่งบรรทัดหลายบรรทัดก่อนที่จะเพิ่มความกระจ่างยิ่งขึ้น อย่างไรก็ตามคุณควรเรียกใช้สิ่งนี้ในฐานะ superuser ดังนั้นจึงอาจไม่เหมาะสม (อาการ: บนแล็ปท็อปที่ฉันลองใช้มันแสดงรายการดิสก์ 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 -do ชื่อทราน
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

ฉันกำลังมองหาสิ่งนี้ในคำตอบ
Eduard Florinescu

4

สิ่งนี้ไม่ต้องการสิทธิ์รูท (แต่คำสั่งเหล่านี้จำนวนมากใช้และขึ้นอยู่กับ 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ค่า (ซึ่งเป็น 52 ในsdaตัวอย่างของฉันด้านบน) มีการ1ตั้งค่าบิต (เช่นไม่ว่าจะเป็นจำนวนคี่)

แต่ลีนุกซ์ให้ค่าสถานะทั้งหมด/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

ในระบบของฉันมีปุ่ม USB 4 อัน แต่หนึ่งในนั้น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 ที่ทำให้ส่วนแรกของคำตอบของฉันอ่านง่ายขึ้น
F. Hauri

1
(1) ทำไมคุณถึงมีเครื่องหมายปีกกาซ้อนกัน? คุณหมายถึง…,device/{model,type,vendor,uevent}อะไร (2) คุณช่วยอธิบายคำสั่ง GENHD และคำสั่ง "ติดตาม / เปิดใช้งาน" ของคุณได้หรือไม่? (3) ของคุณ[ $(( $(< $file ) & 1 )) -ne 0 ]ทดสอบได้ง่าย (สั้นลง) (( $(< $file ) & 1 ))เพื่อ
G-Man กล่าวว่า 'Reinstate Monica'

@ G-Man (1) ใช่ +1 สำหรับสิ่งนี้! ฉันไม่เข้าใจว่าการแนะนำ tipo นี้เป็นอย่างไร (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) ใช่
F. Hauri

0

ฉันขอแนะนำเพียงแค่ใช้hdparmหรือlshw(ซึ่งคุณอาจต้องติดตั้ง) และใช้sudoในการดำเนินการมันเป็นราก

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 หรือสื่อแบบถอดได้อื่น ๆ )


ข้อมูลนี้ซ้ำในคำตอบของ F. Hauriและไม่เพิ่มเนื้อหาใหม่ โปรดอย่าโพสต์คำตอบเว้นแต่ว่าคุณจะสามารถเพิ่มแง่มุมใหม่ ๆ ที่ไม่พบในคำตอบที่มีอยู่
G-Man กล่าวว่า 'Reinstate Monica'

0

dmesg เป็นวิธีที่ง่ายที่สุด:

dmesg | grep sd X

(sdXเป็นชื่ออุปกรณ์ของคุณเช่นsda)

จากคำสั่งด้านบนคุณจะเห็นสิ่งต่อไปนี้:

  • ดิสก์ 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ฉันจะรู้ได้อย่างไรว่าเป็น HDD ในตัวหรือคีย์ USB” โปรดอธิบายว่า OP สามารถใช้คำสั่งของคุณอย่างไร การกำหนด. (2) เราต้องการคำตอบที่ให้คำสั่งและอธิบายมากกว่าคำตอบที่ให้คำสั่งเท่านั้น โปรดอธิบายสิ่งที่คุณกำลังทำ กรุณาอย่าตอบในความคิดเห็น; แก้ไขคำตอบของคุณเพื่อให้ชัดเจนและสมบูรณ์ยิ่งขึ้น … (ต่อ)
G-Man พูดว่า 'Reinstate Monica'

(ต่อ): (3)  awkเป็นเครื่องมือที่ทรงพลังมาก เริ่มต้นหลายคนโพสต์คำตอบที่ทำและท่อส่งออกไปสู่grep awkสิ่งนี้ไม่ค่อยจำเป็น สามารถทำจับคู่รูปแบบและสามารถเลือกการป้อนข้อมูลที่ต้องการโดยไม่ต้องความช่วยเหลือจากawk grepคุณมีไพพ์ไลน์ของสองgrepคำสั่งแล้วไพพ์ไปยังawkจากนั้นคำสั่งที่สอง awkสิ่งนี้สามารถทำให้ง่ายขึ้นอย่างมาก โปรดลอง (4) นอกจากนี้เพื่อความชัดเจนคุณอาจต้องการที่จะเปลี่ยน`…`ไป$(…)- เห็นนี้ , นี้และนี้
G-Man กล่าวว่า 'Reinstate Monica'

0

ฉันขี้เกียจ, inxi บอกเรื่องนี้ได้อย่างง่ายดาย:

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 mounts


-1

หลังจากที่คุณเสียบอุปกรณ์ USB ให้เรียกใช้dmesgในหน้าต่างคอนโซล คุณจะได้รับคำแนะนำบางอย่าง

ตัวอย่างเช่นมันจะพูดอะไรบางอย่างตามสายของ "อุปกรณ์เสียบเข้าที่เก็บข้อมูลขนาดใหญ่ / dev / sdd"


2
กรุณาให้ข้อมูลเพิ่มเติม / ชี้แจงเพื่อให้คำตอบของคุณมีประโยชน์
George M

2
วิธีการไม่ดูถูกเมื่อตอบคำถาม?
Shadur
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.