답변:
Peter는 나에게 "ata0.00"과 같은 바보 같은 것들을 출력하는 대신 USB 스틱을 감지 할 수있는 고급 스크립트 (let)를 작성하도록 영감을주었습니다. Peter의 스크립트와 달리 동일한 컨트롤러 resp에 둘 이상의 장치가있는 경우 하위 번호 (4.01에서와 같이)도 얻습니다. 채널. 결과는에서 얻을 수있는 그대로입니다 syslog
. 테스트했습니다. 항상 많은 개선이 있지만 (예 : 너무 서투른 정규 표현식) 데비안 상자에서 잘 작동합니다. 그러나 그것을 잡아라! 내 정규 표현식에서 찾을 수있는 너무 많은 이스케이프 문자는 호환성상의 이유입니다! GNU sed
를 모든 사람과 함께 할 수는 없기 때문에 의도적으로 확장 정규 표현식을 사용하지 않았습니다.
업데이트
(1) 더 이상 ls
출력을 구문 분석하지 않습니다 . (oops!) 모두 알고 있으므로 ls를 구문 분석하지 마십시오.
(2) 이제 읽기 전용 환경에서도 작동합니다.
이 잡담에서 제안에서 영감을 (3) 여기 내가 다시 나오지 제표 방법은 덜 복잡로 처리했다.
#!/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"로 시작하는 줄을 찾으십시오.
자세한 설명 대신 스크립틀릿을 선호합니다. 이것은 내 우분투 상자에서 작동합니다. 원하는대로 의견을 추가하십시오.
# 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
따라서에 scsi_host/host3
번역 3:x:x:x
할 수 있습니다 dmesg
. 자세한 정보를 얻으 려면 grep 할 수 있습니다 .
# 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)를 혼합하지 않은 경우 가장 낮은 번호의 장치는 cdrom 장치가 아닌 한 sda가됩니다.
시스템에 따라 sysfs를 돌아 다니면서 신성 할 수도 있습니다. 내 시스템에 ls -l /sys/dev/block
그 계시 8:0
:에 점 (주요 / dev에 항목에서 미성년자) /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은 /sys/dev/block/
목록 에서 host : channel : ID : LUN 폴더의 "ID"에 매핑되어야합니다 . 여러 경우 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 장치 이름, 크기 , 모델 , s / n 및 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
(우분투 12.04 / 14.04 및 CentOS 6에서만 테스트 됨)
이 정보 등을 찾기위한 스크립트는 https://www.av8n.com/computer/disk-hw-host-bus-id 에서 찾을 수 있습니다.
Mr. Syntaxerror가 제공 한 스크립트와 비슷하지만 더 환상적입니다. -ATA 드라이브뿐만 아니라 USB 드라이브에서도 작동합니다. -드라이브 제조업체, 모델 및 일련 번호 및 물론 연결 지점을 제공합니다. -더 간단하고 읽기 쉽고 유지 관리가 쉽습니다.