Preparar um Pendrive com FAT32 a prova de Burrice

fevereiro 23rd, 2015 by rudsonalves Leave a reply »

A muito tempo que não escrevo um script em bash e percebo que estou muito enferrujado. No entanto, depois de algumas tentativas e erros, com muitas consultas ao man e a rede, o script saiu.

A ideia deste script é eliminar um potencial acidente, a qual já me deixou sem sistema operacional e sem meus preciosos documentos, arquivos, planilhas, projetos, …, ao menos umas três vezes ao longo destes últimos 15 anos de computação. A estória somente não foi pior nas últimas ocorrências pois me tornei sistemático o suficiente para manter backups, ao menos bimestrais, nos últimos anos.

O problema vem na execução de comandos básicos como o dd e o fdisk em meros pendrives de uso geral. Procedimentos comuns que devemos fazer sempre que instalamos um sistema novo em alguma máquina, através do pendrive, ou simplesmente se deseja formatar o dispositivo. Não foi uma vez em que troquei o /dev/sdb por um /dev/sda, e neste momento o sistema foi para o saco.

Na última trágica ocasião em que isto aconteceu, me lembro que estava do meio para o final do semestre na universidade, e perdi notas de provas, de trabalhos e outras atividades, enquanto que o meu backup mais recente datava de quase um ano atrás.

Na ocasião fui obrigado a aprender a utilizar o TestDisk para recuperar as informações perdidas do disco rígido recém particionado/formatado e felizmente recuperei a maior parte das informações primordiais. Na ocasião, até pensei em fazer um tutorial a respeito do processo, no entanto o desespero para a recuperação dos dados foi tamanho que achei mais conveniente concentrar minha minha atenção em recuperar os dados, deixando o texto para uma outra ocasião. O TestDisk está anotado em minha lista de futuros artigos.

A intenção deste texto não é ser um texto de orientação a criação de bash scripts, mas apenas documentar uma experiencia em tentar tornar o uso do sistema menos destrutivo, em tarefas básicas.

A Ideia do Script

A ideia do script é que este seja inteligente o suficiente para impedir que erros tolos, como formatar um disco em uso não ocorram. Para isto tracei as seguintes premissas para o script:

  • Não particionar/formatar dispositivos com partições montadas;
  • Não particionar/formatar discos definidos como disco de sistema.

A primeira premissa é feita na linha 18, onde os dispositivos montados são listados na variável MOUNTEDDEVS, através de uma consulta ao comando df.

Quanto à segunda premissa, havia a possibilidade de consultar o arquivo /etc/fstab. Mas devido a possibilidade do uso dos códigos UUID para indicar as partições dos disco, o que virou padrão na maioria das distribuições, optei por adicionar os disco do sistema em uma variável, SYSDEVICES, como dispositivos reservados para o sistema. Esta variável esta definida na linha 20 com os dispositivos sda e sdb, que são os dois discos que compõem o meu sistema.

Como medida de segurança adicional, o aplicativo apenas formata os discos do sistema se estes estiverem desmontados e a opção --force for passada para o script.

Como particionamento/formatação de um dispositivo é algo muito destrutivo, o script ainda irá pedir uma confirmação antes de executar os comandos, linha 88.

O dispositivo a ser particionado/formatado pode ser passado como parâmetro com a opção -d <device>. Se este não for passado, o último dispositivo conectado a uma das portas USB será selecionado com uma consulta nas últimas linhas do comando dmesg, linha 48.

Adicionei ainda: uma opção de warning, -w, para simular os comandos sem de executá-los; uma opção para adicionar um label para o dispositivo, -n; além do help do script, -h.

O script completo segue abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/bin/bash 
#
# Create a new FAT32 partition on the stick and write a FAT32 
# filesystem on it.
#
 
function help()
{
    echo "Use: # `basename $0` [options]:"
    echo "    Where:"
    echo "        -d <device = sda, sdb, sdc, ...>"
    echo "        -n <device name = string>"
    echo "        --force (to force format of SYSDEVICES)"
    echo "        -w (warning mode. Don't format)"
    echo "        -h for help"
}
 
MOUNTEDDEVS=`df -h | grep '^\/dev\/sd[a-z]' | cut -c-8 | sort | uniq | cut -c6-`
FORCE=false
SYSDEVICES="sda sdb"
WARN=false
 
while [ ! -z $1 ]; do
    case $1 in
        '-d')
            DEV=$2
            shift
            ;;
        '-n')
            DEVNAME=$2
            shift
            ;;
        '--force')
            FORCE=true
            ;;
        '-w')
            WARN=true
            ;;
        '-h'|*)
            help
            exit 0
            ;;
    esac
    shift
done
 
if [ -z "$DEV" ]; then
    DEV=`dmesg | tail | grep '\[.*\] *sd[bcdefg]' | rev | cut -d" " -f1 | rev | tr -d ':0123456789' | head -n1`
fi
 
if [ -z "$DEVNAME" ]; then
    DEVNAME="USBDisk"
fi
 
echo -n "Check by mounted devices: "
for dev in $MOUNTEDDEVS; do
    if [ "$dev" == "$DEV" ]; then
        # Abort format of mounted devices
        echo "mounted..."
        echo "Device /dev/$DEV is in use. To format it you need umount all partitions this device before."
        df -h | grep "^\/dev\/$DEV"
        exit 0
    fi
done
echo "Device isn't mounted..."
 
echo -n "Check by System devices: "
SYSDEV=false
for dev in $SYSDEVICES; do
    if [ "$dev" == "$DEV" ]; then
        SYSDEV=true
        if $FORCE; then
            echo "Is a system device, but forced enable..."
            break
        fi
        echo -e "Is a system device...\n"
        echo "Use --force option to format a system device, or edit SYSDEVICES variable in this script."
        exit 0
    fi
done
if ! $SYSDEV; then
    echo "Is not a system device..."
fi
 
echo -ne "\nFormat device /dev/${DEV} with name ${DEVNAME} (y/N)? "
read ANS
 
if [ "$ANS" != "Y" -a "$ANS" != "y" ]; then
    exit 0
fi
 
echo -e "\nClear first 10MB..."
if $WARN; then
    echo "dd if=/dev/zero of=/dev/$DEV bs=1M count=10"
else
    dd if=/dev/zero of=/dev/$DEV bs=1M count=10
fi
 
echo -e "\nRemove partitions in device /dev/${DEV} ..."
 
if $WARN; then
    echo "fdisk /dev/$DEV <<EOF
n
p
1
 
 
t
b
w
EOF"
 
else
    fdisk /dev/$DEV <<EOF
n
p
1
 
 
t
b
w
EOF
fi
 
echo -e "\nFormat device /dev/${DEV}1 with FAT32 filesystem..."
if $WARN; then
    echo "mkdosfs -n ${DEVNAME} -F32 /dev/${DEV}1"
else
    mkdosfs -n ${DEVNAME} -F32 /dev/${DEV}1
fi

Uso do Script

Chamei o script de usbfat32, uma vez que no momento é um script especializado para formatar dispositivos USB em FAT32. Mas é possível que adiante estenda a ideia. As linhas a seguir mostram alguns exemplos de uso:

Limpa a tabela de partição do dispositivo /dev/sdc, formata em FAT32 e configura o nome do dispositivo para ‘Alves’:

root@luskan:# usbfat32 -d sdc -n Alves

Limpa a tabela de partição do dispositivo recém inserido a porta USB, formata em FAT32 e configura o nome do dispositivo para ‘Alves’:

root@luskan:# usbfat32 -n Alves

O mesmo que o comando anterior, mas sem executar nada:

root@luskan:# usbfat32 -n Alves -w

A próxima linha de comando mostra o que acontece ao tentar formatar um dispositivo montado:

root@luskan:# usbfat32 -d sda
Check by mounted devices: mounted...
Device /dev/sda is in use. To format it you need umount all partitions this device before.
/dev/sda1        25G  8.4G   17G  34% /
/dev/sda4       102G   14G   89G  14% /home

Neste último comando o dispositivo está desmontado, mas está assinalado como sendo dispositivo do sistema:

root@luskan:# usbfat32 -d sdb
Check by mounted devices: Device isn't mounted...
Check by System devices: Is a system device...

Use --force option to format a system device, or edit SYSDEVICES variable in this script.

Neste último caso, se usar a opção --force o dispositivo /dev/sdb será particionado e em seguida formatado em FAT32.

Conclusões

O script está com o código ainda tosco, necessitando de um pouco de lapidação, como disse estou muito sem prática. No entanto faz bem o seu papel. Acho que assim ao menos fica reduzida a probabilidade de formatar o HD no lugar do pendrive. Os interessados em melhorar a ideia estão convidados a compartilhar.


QR Code
Advertisement

5 comments

  1. AnN disse:

    Olá! Primeiramente, gostaria de parabenizá-lo pelo ótimo trabalho que vem realizando neste site!

    São poucos os sites que compartilham dicas e informações a respeito do Slackware.

    Gostaria de fazer parceria, também tenho um blog destinado ao Slackware. Se tiver interesse, entre em contato comigo via email.

  2. rudsonalves disse:

    Ola AnN, valeu. Lhe mandei um email. No entanto deveria ter deixado o endereço de seu blog.

  3. AnN disse:

    Olá @rudsonalves,

    me desculpe a demora, devido ao trabalho e a faculdade também não estou tendo tempo de atualizar meu blog, e acabei esquecendo de responder teu email. Como perdi o endereço do seu email na minha caixa de entrada (o gmail deleta automaticamente após um tempo), então voltei aqui para respondê-lo. Coloquei o endereço do blog no campo Web Site, conversaremos por email se ainda quiser manter parceria. Até mais, abraços!

  4. netto disse:

    Bacana seus artigos…. pena que o Facebook não permite compartilha-los em lugar nenhum porque o seu domínio está identificado como nocivo.
    Abraços

  5. rudsonalves disse:

    Se lhe acrescentou algo está ótimo Netto

Deixe uma resposta

This blog is kept spam free by WP-SpamFree.