USB removível listado como não removível em / sys / block?

4

Na minha pergunta Script Bash para saída do caminho para o stick de memória flash USB Fiquei preso a um problema que ninguém mais parece estar tendo. (O problema também impede meu desejo de usar essa resposta: link .)

Então, eu coloquei esse problema específico nessa nova pergunta.

Dispositivos aparentemente removíveis listados em / sys / block terminam em 1. É indicado aqui: link e vários outros lugares neste link e este princípio é usado nas respostas que referi acima.

Meu dispositivo removível, um pen drive de 64GB da Sandisk, está listado como:

/sys/block/sdl/removable:0

Aparentemente, os dispositivos removíveis devem terminar em 1 (e os meus outros). Por que minha memória USB não segue a regra?

Ele foi montado automaticamente pelo Dolphin. Estou executando o Kubuntu 12.04.

O Dolphin mostra como "Mídia Removível de 59.6GiB".

E ele é montado (automaticamente) em / media / me / 70E8-1567

sudo blkid mostra como:

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

'lsblk -do nome, rm' mostra:

sdl   0

E lsusb -vv mostra:

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
    
por MountainX 15.03.2014 / 00:38

3 respostas

1

Seletor de armazenamento removível USB: USBKeyChooser

Acho que tenho:

Substituir grep -Hv 0 /sys/block/*/removable por grep -Hv ^ATA\ *$ /sys/block/*/device/vendor parece funcionar:

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 -e s/\ *$//g </sys/block/$dev/device/model
        )\" ;
  done

Ou mesmo usando readlink para garantir que isso é USB poderia ser mais preciso ...

export USBKEYS=($(
    xargs -n1 readlink < <(echo /sys/block/*) |
    sed -ne 's+^.*/usb[0-9].*/\([^/]*\)$+/sys/block//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 -e s/\ *$//g </sys/block/$dev/device/model
        )\" ;
  done

Retroceder:

Neste eu

  1. Certifique-se de que esta é USB (ou removível

  2. Garanta esse trabalho como um disco rígido (não um CD-Rom)

  3. Verifique se eles têm tamanho maior que 0 (não um leitor de cartão vazio)

Versão com golfe:

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=

Isso pode ser escrito

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

Com readlink , a versão com golf se torna:

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

Em bom: usbKeyChooser

Existe a versão final da sub-rotina usbKeyChooser no meu live installer :

#!/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//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

Eu gosto dessa solução looping porque eles

  • vamos inserir muitas chaves,
  • aguarde o registro do kernel,
  • valida a escolha,
  • padrão para nada e
  • permite o cancelamento do usuário.

De qualquer forma, mesmo que o usuário tenha errado ok choice, a próxima tela é outra opção perguntando ao usuário para qual imagem precisa ser escrita na chave padrão para criar nova imagem que é um processo muito longo onde o usuário pode pressionar Ctrl + c

    
por 15.03.2014 / 12:24
4

Ok, para puxar isso em uma lista, você pode usar o mesmo comando que dei a você antes , mas solte o requisito removível :

% 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 

Não é grande coisa - agora só produzirá pontos de montagem ativos para dispositivos de bloco no barramento usb e, de qualquer forma, não consigo pensar em muitos exemplos de dispositivos de bloco usb não removíveis.

Em relação a por que seu dispositivo atual não se registra como removível, a resposta mais provável é que o driver simplesmente não o lista dessa maneira. Quando os dispositivos são detectados por udev , ele obtém informações sobre eles assim que possível, com base em seu banco de dados de regras. Você pode ver todas essas classificações com:

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

Isso retornará uma lista de todas as entradas key = value que o sistema usa para classificar o hardware mencionado por /dev/$BLOCK_DEVICE . Na parte inferior de este post slm aconselha como essa informação pode ser facilmente analisada para atender às suas necessidades - e é bem simples de fato. A documentação descreve-o corretamente como "human-readable, grep-friendly". Acima eu filtro todos os dispositivos de bloco para apenas aqueles no barramento usb com:

% grep -q ID_BUS=usb

Você também pode usar attribute-walk na árvore de dispositivos do seu dispositivo atual e outra attributes que acha que deve refletir. Se isso não acontecer, é porque udev atribuiu isso de forma diferente do que você acha que deveria ter. Felizmente, no entanto, você pode ver todos os pontos de dados que afetaram sua atribuição:

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

Você pode usar esses dados para modelar novas regras de atribuição conforme desejar.

    
por 15.03.2014 / 05:21
0

Esta é a resposta de F. Hauri adaptada para 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//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
    
por 16.03.2014 / 03:59