Answers:
彼得启发我写了一个高级脚本(let),它甚至可以检测USB记忆棒(而不是输出“ ata0.00”之类的愚蠢东西)。与Peter的脚本相反,如果在同一控制器上有多个设备,则还将获得子编号(如4.01)。渠道。输出将完全与您获得的一样syslog
。经过测试。尽管总会有很多改进(例如,正则表达式太笨拙),但在我的Debian机器上工作得很好。但是,请坚持!您可能在我的正则表达式中发现的转义字符数量似乎过多,仅出于兼容性原因!您不能sed
与所有人一起使用GNU ,这就是为什么我没有故意扩展regexp的原因。
更新
(1)将不再解析ls
输出。(糟糕!)既然大家都知道:不要解析ls。
(2)现在也可以在只读环境中使用。
(3)通过从该闲聊的建议启发这里我已成功地再次拿到sed的报表方式不太复杂。
#!/bin/bash
# note: inspired by Peter
#
# *UPDATE 1* now we're no longer parsing ls output
# *UPDATE 2* now we're using an array instead of the <<< operator, which on its
# part insists on a writable /tmp directory:
# restricted environments with read-only access often won't allow you that
# save original IFS
OLDIFS="$IFS"
for i in /sys/block/sd*; do
readlink $i |
sed 's^\.\./devices^/sys/devices^ ;
s^/host[0-9]\{1,2\}/target^ ^ ;
s^/[0-9]\{1,2\}\(:[0-9]\)\{3\}/block/^ ^' \
\
|
while IFS=' ' read Path HostFull ID
do
# OLD line: left in for reasons of readability
# IFS=: read HostMain HostMid HostSub <<< "$HostFull"
# NEW lines: will now also work without a hitch on r/o environments
IFS=: h=($HostFull)
HostMain=${h[0]}; HostMid=${h[1]}; HostSub=${h[2]}
if echo $Path | grep -q '/usb[0-9]*/'; then
echo "(Device $ID is not an ATA device, but a USB device [e. g. a pen drive])"
else
echo $ID: ata$(< "$Path/host$HostMain/scsi_host/host$HostMain/unique_id").$HostMid$HostSub
fi
done
done
# restore original IFS
IFS="$OLDIFS"
看一下/proc/scsi/scsi
,它看起来像这样:
$ cat /proc/scsi/scsi
Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
Vendor: ATA Model: ST3250823AS Rev: 3.03
Type: Direct-Access ANSI SCSI revision: 05
Host: scsi1 Channel: 00 Id: 00 Lun: 00
Vendor: ATA Model: ST3750528AS Rev: CC44
Type: Direct-Access ANSI SCSI revision: 05
Host: scsi2 Channel: 00 Id: 00 Lun: 00
Vendor: ATA Model: ST3750330AS Rev: SD1A
Type: Direct-Access ANSI SCSI revision: 05
Host: scsi10 Channel: 00 Id: 00 Lun: 00
Vendor: WDC WD20 Model: EARS-00MVWB0 Rev:
Type: Direct-Access ANSI SCSI revision: 02
scsi0 id 0是sda和ata1.00,scsi1 id 0是sdb和ata2.00,依此类推。
还要查看/var/log/dmesg
,它显示了ata驱动程序的加载信息,并使您的情况更加清楚。查找以“ libata”开头的行。
我更喜欢scriptlet而不是冗长的解释。这适用于我的Ubuntu盒子。根据自己的喜好添加评论:
# on Ubuntu get ata ID for block devices sd*
ls -l /sys/block/sd* \
| sed -e 's^.*-> \.\.^/sys^' \
-e 's^/host^ ^' \
-e 's^/target.*/^ ^' \
| while read Path HostNum ID
do
echo ${ID}: $(cat $Path/host$HostNum/scsi_host/host$HostNum/unique_id)
done
ls -l /sys/block/sd* | sed -e 's@.*-> \.\..*/ata@/ata@' -e 's@/host@ @' -e 's@/target.*/@ @'
这实际上很棘手。虽然可以安全地假设“ scsi ID”是“ SATA ID减1”,但我还是比较安全,并检查一下unique_id
我基于SATA标识符(根据本帖子)。
我的错误是:
[6407990.328987] ata4.00: exception Emask 0x10 SAct 0x1 SErr 0x280100 action 0x6 frozen
[6407990.336824] ata4.00: irq_stat 0x08000000, interface fatal error
[6407990.343012] ata4: SError: { UnrecovData 10B8B BadCRC }
[6407990.348395] ata4.00: failed command: READ FPDMA QUEUED
[6407990.353819] ata4.00: cmd 60/20:00:28:c2:39/00:00:0c:00:00/40 tag 0 ncq 16384 in
[6407990.353820] res 40/00:00:28:c2:39/00:00:0c:00:00/40 Emask 0x10 (ATA bus error)
[6407990.369618] ata4.00: status: { DRDY }
[6407990.373504] ata4: hard resetting link
[6407995.905574] ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
[6407995.976946] ata4.00: configured for UDMA/133
[6407995.976961] ata4: EH complete
所以我的程序来找出是什么ata4
:
查找SATA控制器的PCI ID
# lspci | grep -i sata
00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
找到匹配的唯一ID:
# grep 4 /sys/devices/pci0000:00/0000:00:1f.2/*/*/*/unique_id
/sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/unique_id:4
因此它位于on scsi_host/host3
,我们可以将其翻译为3:x:x:x
,我们可以对其进行grep dmesg
查找以了解更多信息:
# dmesg | grep '3:.:.:.'
[ 2.140616] scsi 3:0:0:0: Direct-Access ATA ST3250310NS SN06 PQ: 0 ANSI: 5
[ 2.152477] sd 3:0:0:0: [sdd] 488397168 512-byte logical blocks: (250 GB/232 GiB)
[ 2.152551] sd 3:0:0:0: [sdd] Write Protect is off
[ 2.152554] sd 3:0:0:0: [sdd] Mode Sense: 00 3a 00 00
[ 2.152576] sd 3:0:0:0: [sdd] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 2.157004] sd 3:0:0:0: [sdd] Attached SCSI disk
[ 2.186897] sd 3:0:0:0: Attached scsi generic sg3 type 0
这是我们的设备,在RAID阵列完全失效之前,我们可以(可选)找到将设备从那里拿出的序列号(或检查电缆连接等):
# hdparm -i /dev/sdd | grep Serial
Model=ST3250310NS, FwRev=SN06, SerialNo=9SF19GYA
大功告成!
我遇到了同样的问题,并且能够通过检查dmesg来识别驱动器。在这里,您可以看到控制器标识符(正确的术语??)和磁盘型号。然后使用ls -l / dev / disk / by-id将型号匹配到/ dev / sda(或其他)。另外,我喜欢“磁盘工具”来获取此信息。注意:这仅在磁盘具有不同型号时才有效,否则,您将无法在两者之间进行区分。
>dmesg |grep ata
...
[ 19.178040] ata2.00: ATA-8: WDC WD2500BEVT-00A23T0, 01.01A01, max UDMA/133
[ 19.178043] ata2.00: 488397168 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
[ 19.179376] ata2.00: configured for UDMA/133
[ 19.264152] ata3.00: ATA-8: WDC WD3200BEVT-00ZCT0, 11.01A11, max UDMA/133
[ 19.264154] ata3.00: 625142448 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
[ 19.266767] ata3.00: configured for UDMA/133
...
>ls -l /dev/disk/by-id
lrwxrwxrwx 1 root root 9 Feb 18 12:17 ata-WDC_WD2500BEVT-00A23T0_WD-WXE1A7131446 -> ../../sda
lrwxrwxrwx 1 root root 10 Feb 18 11:48 ata-WDC_WD2500BEVT-00A23T0_WD-WXE1A7131446-part1 -> ../../sda1
lrwxrwxrwx 1 root root 9 Feb 18 12:17 ata-WDC_WD3200BEVT-00ZCT0_WD-WXHZ08045183 -> ../../sdb
lrwxrwxrwx 1 root root 10 Feb 18 11:48 ata-WDC_WD3200BEVT-00ZCT0_WD-WXHZ08045183-part1 -> ../../sdb1
最简单的方法是从启动中查看内核日志,因为驱动器设备名称是从各种来源(例如USB驱动器)混入的,或者是根据设备类型分配的(即cdrom可能是scdX,而所有内容都有sgX) )。实际上,除非您混用了各种总线(例如SATA + USB),否则编号最低的ata设备将是sda,除非它是cdrom设备。
根据您的系统,它可能会因在sysfs上徘徊而占卜。在我的系统上ls -l /sys/dev/block
显示8:0
(/ dev条目中的main:minor)指向/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
同样,ls -l /sys/class/ata_port
表明ata1
指向/sys/devices/pci0000:00/0000:00:1f.2/ata1/ata_port/ata1
同一PCI子设备上的指向。
由于我使用SATA,并且每个端口上只有一个驱动器,因此我可以推断出ata1.00 = sda。我所有的驱动器都是.00,我怀疑如果使用端口倍增器,我的驱动器将得到.01,.02,.03等。查看其他人的日志PATA控制器将.00和.01用作主服务器和从属服务器。 ,并根据其日志(如果您有ataX.01),将.01映射到列表中host:channel:ID:LUN文件夹中的“ ID” /sys/dev/block/
。如果有多个ataX/
与hostY/
文件夹相同的PCI设备的文件夹,然后我怀疑最低编号ataX文件夹相匹配的最低编号HOSTY文件夹。
在中/sys/class/ata_port/ata${n}/device/
,您可以看到一个host${x}
文件夹。例如,在我的机器上:
gibby ~ # ls /sys/class/ata_port/ata1/device/
ata_port host0 link1 power uevent
gibby ~ # ls /sys/class/ata_port/ata2/device/
ata_port host1 link2 power uevent
gibby ~ # lsscsi
[0:0:0:0] disk ATA WDC WD1002FAEX-0 1D05 /dev/sda
[1:0:0:0] disk ATA WDC WD2001FFSX-6 0A81 /dev/sdb
[2:0:0:0] disk ATA WDC WD1002FAEX-0 1D05 /dev/sdc
[3:0:0:0] disk ATA WDC WD2001FFSX-6 0A81 /dev/sdd
[5:0:0:0] disk ATA SAMSUNG MZ7TD256 2L5Q /dev/sde
在${x}
中host${x}
是指在那个第一个数字[0:0:0:0]
。所以对我来说ata1
是指host0
其也可以在SCSI形式来表示0:*
:
gibby ~ # lsscsi 0:\*
[0:0:0:0] disk ATA WDC WD1002FAEX-0 1D05 /dev/sda
下面的脚本将为您提供一个不错的摘要,如下所示:
sda [ 180.0 GB] INTEL SSDSC2BW180A4, BTDA4052066D1802GN pci0000:00/0000:00:11.0/ata1/host0/target0:0:0/0:0:0:0/block/sda
sdb [ 1000.2 GB] WDC WD1000DHTZ-04N21V1, WD-WXM1E83CNTX5 pci0000:00/0000:00:11.0/ata3/host2/target2:0:0/2:0:0:0/block/sdc
sdc [ ------ GB] -- pci0000:00/0000:00:12.2/usb1/1-5/1-5:1.0/host6/target6:0:0/6:0:0:0/block/sdf
因此,每个驱动器一行中有sdX设备名称,大小,型号,序列号和pci和ata号。上面的sdc对应于未插入卡的USB SD卡读取器。因此,----代替了真实信息。
#!/bin/bash
BLKDEVS=`ls -l /sys/block/sd*|sed -e 's/^.* -> //' -e 's/^...devices.//'`
echo $BLKDEVS|tr \ \\n |sort| \
while read DISK ; do
SD=`echo $DISK|sed -e 's/^.*\///'`
INFO=`hdparm -i /dev/$SD 2>/dev/null|grep Model=|sed -e 's/Model=//' -e 's/FwRev=[^ ]*//' -e 's/SerialNo=//'`
! [[ $INFO ]] && INFO='--'
SIZE=`fdisk -l /dev/$SD 2>/dev/null|grep '^Disk .* bytes'|sed -e 's/^[^,]*, \([0-9]*\) bytes$/\1/'`
if [[ $SIZE ]] ; then
SIZE=`echo $SIZE|awk '{printf "[%7.1f GB]" , $1/1000/1000/1000}'|tr \ _`
else
SIZE='[ ------ GB]'
fi
echo $SD $SIZE $INFO $DISK
done
(仅在ubuntu 12.04 / 14.04和CentOS 6上进行了测试)
可以在以下位置找到找到此信息的脚本以及更多信息。 https://www.av8n.com/cn/computer/disk-hw-host-bus-id中
它与Syntaxerror先生提供的脚本相似,但更新颖。-它适用于USB驱动器和ATA驱动器。-它提供了驱动器的品牌和型号以及序列号-当然还有连接点。-它更加简单,可读和可维护。