Съемный USB-накопитель, указанный как несъемный в / sys / block?

В моем вопросе сценарий Bash для вывода пути на флеш-накопитель USB я застрял в проблеме, которую, похоже, никто не имеет. (Проблема также мешает моему желанию использовать этот ответ: https://unix.stackexchange.com/a/60335/15010 .)

Поэтому я задал эту конкретную проблему в этом новом вопросе.

Очевидно, съемные устройства, перечисленные в / sys / block end с 1. Здесь говорится: https://unix.stackexchange.com/a/80880/15010 и несколько других мест в этом http://unix.stackexchange.com и это принцип используется в ответах, на которые я ссылался выше.

Мое съемное устройство, флеш-накопитель Sandisk 64 ГБ, указано как:

/sys/block/sdl/removable:0 

По-видимому, съемные устройства должны заканчиваться на 1 (и мои другие). Почему мой USB-накопитель не соответствует правилу?

Он был оборудован Дельфином. Я запускаю Kubuntu 12.04.

Дельфин показывает это как «59.6GiB Removable Media».

И он устанавливается (автоматически) на / media / me / 70E8-1567

sudo blkid показывает это как:

 /dev/sdl1: UUID="70E8-1567" TYPE="vfat". 

'lsblk -do name, rm` показывает:

 sdl 0 

И lsusb -vv показывает:

 Bus 001 Device 008: ID 0781:5530 SanDisk Corp. Cruzer Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0781 SanDisk Corp. idProduct 0x5530 Cruzer bcdDevice 2.01 iManufacturer 1 iProduct 2 iSerial 3 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 200mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 8 Mass Storage bInterfaceSubClass 6 SCSI bInterfaceProtocol 80 Bulk-Only iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 1 

  • Застрял на «Прикрепленный съемный диск SCSI», пытающийся установить Linux Mint
  • Возможно ли создать загрузочный USB-диск из раздела?
  • Как скопировать очень большой видеофайл с ошибкой в ​​нем?
  • Безопасное извлечение флеш-накопителя USB
  • Изменение прав доступа к файлу FAT32 с автоматическим подключением
  • Как найти скрытый раздел USB в Linux
  • USB-накопители Automount на Gentoo
  • Есть ли способ изменить идентификатор устройства в / dev / disk / by-id?
  • 3 Solutions collect form web for “Съемный USB-накопитель, указанный как несъемный в / sys / block?”

    Я думаю, что у меня есть это:

    Замена grep -Hv 0 /sys/block/*/removable grep -Hv ^ATA\ *$ /sys/block/*/device/vendor похоже, работает:

     export USBKEYS=($( grep -Hv ^ATA\ *$ /sys/block/*/device/vendor | sed s/device.vendor:.*$/device\\/uevent/ | xargs grep -H ^DRIVER=sd | sed s/device.uevent.*$/size/ | xargs grep -Hv ^0$ | cut -d / -f 4 )) for dev in ${USBKEYS[@]} ;do echo $dev \"$( sed -es/\ *$//g </sys/block/$dev/device/model )\" ; done 

    Или даже используя readlink чтобы гарантировать, что USB может быть более точным …

     export USBKEYS=($( xargs -n1 readlink < <(echo /sys/block/*) | sed -ne 's+^.*/usb[0-9].*/\([^/]*\)$+/sys/block/\1/device/uevent+p' | xargs grep -H ^DRIVER=sd | sed s/device.uevent.*$/size/ | xargs grep -Hv ^0$ | cut -d / -f 4 )) for dev in ${USBKEYS[@]} ;do echo $dev \"$( sed -es/\ *$//g </sys/block/$dev/device/model )\" ; done 

    Rewind:

    В этом я

    1. Убедитесь, что это USB (или съемный

    2. Убедитесь, что эта работа является жестким диском (а не CD-Rom)

    3. Убедитесь, что они имеют размер больше 0 (а не пустой считыватель карт)

    Версия для гольфа:

     US=($(cut -d/ -f4 <(grep -vl ^0$ $(sed s@device/.*@size@ <(grep -l ^DRIVER=sd $( sed s+/device.*$+/dev*/ue*+ <(grep -Hv ^ATA\ *$ /sys/block/*/device/vendor)) <(:))) <(:)))) set | grep ^US= 

    Это можно было бы написать

     US=($( cut -d/ -f4 <( grep -vl ^0$ $( sed s@device/.*@size@ <( grep -l ^DRIVER=sd $( sed -ne 's+^.*/usb[0-9].*/\([^/]*\)$+/sys/block/\1/dev*/ue*+p' <( xargs -n1 readlink < <(echo /sys/block/*) ) ) /dev/null # equivalant but quicker than <(:) )) /dev/null))) 

    С readlink , версия для гольфа станет:

     US=($(cut -d/ -f4 <(grep -vl ^0$ $(sed s@device/.*@size@ <(grep -l ^DRIVER=sd $( sed -ne 's+^.*/usb[0-9].*/\([^/]*\)$+/sys/block/\1/dev*/ue*+p' <( xargs -n1 readlink < <(echo /sys/block/*)) ) <(:))) <(:)))) 

    В итоге:

    Существует окончательная версия подпрограммы usbKeyChooser в моем реальном установщике :

     #!/bin/bash DIALOG=whiptail usbKeyChoose() { while [ ! -b /dev/$STICK ] ;do USBKEYS=($( xargs -n1 readlink < <(echo /sys/block/*) | sed -ne 's+^.*/usb[0-9].*/\([^/]*\)$+/sys/block/\1/device/uevent+p' | xargs grep -H ^DRIVER=sd | sed s/device.uevent.*$/size/ | xargs grep -Hv ^0$ | cut -d / -f 4 )) if [ ${#USBKEYS[@]} -eq 0 ];then title="No key found" else title="Choose wich USB stick have to be installed" fi menu=(R "Re scan devices") for dev in ${USBKEYS[@]} ;do read model </sys/block/$dev/device/model menu+=($dev "$model") done num=$($DIALOG --menu "$title" 21 72 14 "${menu[@]}" 2>&1 >/dev/tty) if [ ! "$num" ] ; then echo "User aborted." exit 0; fi [ ! "$num" = "R" ] && [ "${USBKEYS[num]}" ] && STICK=${USBKEYS[num]} done; } usbKeyChoose echo $STICK 

    Мне нравится это циклическое решение, потому что они

    • пусть вставить много ключей,
    • дождитесь регистрации ядра,
    • действительный выбор,
    • по умолчанию ничего и
    • разрешить пользователю прерывание.

    В любом случае, даже если пользователь сделал неправильный выбор, следующий экран – это еще один выбор, задающий вопрос, для какого изображения нужно писать по умолчанию, чтобы создать новое изображение, которое является очень длинным процессом, когда пользователь может нажать Ctrl + c

    Итак, чтобы вытащить это в список, вы можете использовать ту же самую команду, которую я дал вам раньше , но просто снимите требуемое требование:

     % for blk in $(lsblk -ndo name) ; do > udevadm info --query=all --name "$/dev/$blk" |\ > grep -q ID_BUS=usb && printf \ > 'findmnt %s -no TARGET ;'\ > "/dev/$blk" /dev/"$blk"[0-9] > } ; done 2>&- |. /dev/stdin 

    Это не имеет большого значения – теперь он будет выводить только активные точки монтирования для блочных устройств на шине usb, и я, во-первых, не могу придумать много примеров несъемных блоков USB-устройств в любом случае.

    Что касается того, почему ваше текущее устройство не регистрируется как съемное, наиболее вероятным ответом является то, что его драйвер просто не перечисляет его таким образом. Когда устройства обнаруживаются udev он извлекает информацию о них, как только он может основываться на своей базе данных правил. Вы можете увидеть все эти классификации с помощью:

     % udevadm info --query=all --name /dev/$BLOCK_DEVICE 

    Это вернет список всех записей key = value , используемых системой для классификации аппаратного обеспечения, на которое ссылается /dev/$BLOCK_DEVICE . В нижней части этого сообщения slm советует, как эта информация может быть легко проанализирована для удовлетворения ваших потребностей – и это довольно просто. Документация правильно описывает его как «удобочитаемый, дружелюбный к grep». Выше я фильтрую все блочные устройства только на шинах usb с:

     % grep -q ID_BUS=usb 

    Вы также можете выполнить attribute-walk вплоть до дерева устройств для вашего текущего устройства и другого attributes который, по вашему мнению, должен отражать. Если это не так, это потому, что udev назначил его по-другому, чем вы думаете. К счастью, однако, вы можете видеть каждый datapoint, который повлиял на его назначение:

     udevadm info --attribute-walk --name /dev/$BLOCK_DEVICE 

    Вы можете использовать эти данные для моделирования новых правил назначения, как вам угодно.

    Это ответ Ф. Хаури, адаптированный для kdialog:

     #!/bin/bash DIALOG=kdialog usbKeyChoose() { while [ ! -b /dev/$STICK ] ;do USBKEYS=($( xargs -n1 readlink < <(echo /sys/block/*) | sed -ne 's+^.*/usb[0-9].*/\([^/]*\)$+/sys/block/\1/device/uevent+p' | xargs grep -H ^DRIVER=sd | sed s/device.uevent.*$/size/ | xargs grep -Hv ^0$ | cut -d / -f 4 )) if [ ${#USBKEYS[@]} -eq 0 ];then title="No key found" else title="Choose wich USB stick have to be installed" fi menu=(R "Re scan devices") i=0 for dev in ${USBKEYS[@]} ;do read model </sys/block/$dev/device/model #echo $i $dev "$model" menu+=("$i" "$dev $model") i=$[i + 1] done num=$($DIALOG --menu "$title" "${menu[@]}") #echo "num=$num" #echo "USBKEYS[num]=${USBKEYS[num]}" if [ ! "$num" ] ; then echo "User aborted." exit 0; fi [ ! "$num" = "R" ] && [ "${USBKEYS[num]}" ] && STICK=${USBKEYS[num]} done; } usbKeyChoose echo $STICK 
    Linux и Unix - лучшая ОС в мире.