Điều này không cần đặc quyền gốc (nhưng nhiều lệnh trong số này sử dụng và phụ thuộc vào bashism, vì vậy chúng sẽ không hoạt động trong tất cả các shell tuân thủ POSIX):
Có một cách nhanh chóng để hỏi về :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
Các tập tin thực sự thú vị là capability
. Trên Debian của tôi, tôi có một genhd.h
tập tin, vì vậy:
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
Ở tất cả, chỉ để biết nếu cờ removable
được đặt:
grep REMOVABL /usr/src/linux-headers-3.2.0-4-common/include/linux/genhd.h
#define GENHD_FL_REMOVABLE 1
vì thế
for disk in sd{a,b,c,d,e,f,g,h} ; do
(( $(< /sys/block/$disk/capability ) & 1 )) && echo $disk is removable
done
hoạt động bằng cách kiểm tra xem capability
giá trị (là 52 trong sda
ví dụ của tôi ở trên) có tập 1
bit hay không (nghĩa là nó có phải là số lẻ hay không).
Nhưng Linux kết xuất tất cả các cờ vào /sys
, vì vậy yêu cầu /sys/block/sdX/removable
đơn giản hơn rất nhiều! ;-)
Vì vậy, một chìa khóa USB có thể được removable
, nhưng như có rất nhiều di động thiết bị, tôi muốn để đảm bảo rằng kích thước của môi trường lớn hơn 0 (giống như một khay đĩa CD-ROM dỡ, cho mẫu)
và rằng thiết bị là không trong sử dụng: Trong khi xem mà sdX/trace/enable
không bị ràng buộc:
Nota: Tất cả điều này đã được thử nghiệm tốt trên bash v4.2 +.
Trong bash , bạn có thể sử dụng cách rất nhanh chóng và hiệu quả này:
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
Trên hệ thống của tôi, có 4 phím USB, nhưng một trong số chúng ( sde
) đã được gắn, do đó, đầu ra lệnh trước đó:
sdd 8G Trans-It Drive
sdf 7G Storage Media
sdg 4G silicon-power
Kịch bản của tôi:
Có một chức năng bash nhỏ mà tôi đã viết để cài đặt Debian Live được nâng cấp.
#!/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]}
}
# Phần đầu tiên chỉ hiển thị kích thước có thể đọc được của con người. Các chức năng bắt đầu từ đó.
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
}
Điều này gán câu trả lời, dưới dạng một mảng , cho biến được đưa ra làm đối số đầu tiên hoặc cho biến $REPLY
:
chooseFreeUsbKey stick
echo "$stick"
sdf
echo "${stick[1]}"
7.26G
echo "${stick[2]}"
Storage Media
(Trường cuối cùng có thể chứa khoảng trắng.)