Archive for the ‘Shell Script’ category

Preparar um Pendrive com FAT32 a prova de Burrice

Fevereiro 23rd, 2015

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@computer:# 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@computer:# usbfat32 -n Alves

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

root@computer:# usbfat32 -n Alves -w

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

root@computer:# 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@computer:# 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.

tmux: Um Multiplexador de Terminais

Setembro 16th, 2013

Embora utilize o terminal com bastante frequência a mais de 20 anos, nunca me interessei muito pelo aplicativo screen, o multiplexador de terminais que conhecido desde meus tempos de mestrado na Unicamp.

Recentemente, com a entrada de dois estagiários da Ciência da Computação para trabalhar em desenvolvimento de aplicativos no Laboratório de Física, tenho sido constantemente instigado a remexer alguns comandos e aplicativos, os quais não havia dado muita importância até então.

Com o uso das abas nos gerenciadores de terminal com o konsole do KDE, imaginava que comandos como o screen não teriam muita utilidade, até começar a utilizá-los. Brincando de otimizar o kernel de meu notebook foi que percebi pela primeira vez o quanto pode ser prático um multiplexador de terminais. Dai em diante foi adesão total à ideia.

» Read more: tmux: Um Multiplexador de Terminais

Gnome List – garnome_list

Junho 8th, 2008

Uma das grandes dificuldades em se compilar projetos grandes como o GNOME é justamente conhecer a lista de pacotes utilizadas, além da ordem de compilação dos pacotes. A diversidade de combinações de versões em projetos como estes é imensa. E por isto, se puder pegar uma carona para facilitar o trabalho, não tem porque não o fazer.

» Read more: Gnome List – garnome_list

Mantendo espelhos do Slackware com o Slackmirror

Abril 22nd, 2008

Geralmente mantenho uma cópia do Slackware-Current em minha máquina, para poder acompanhar melhor as novidades para a próxima versão. Programas como o gftp, mc, konqueror, wget entre outros, são muito bons para auxiliarem na manutenção de espelhos como estes, mas sempre deixam algum trabalho adicional, como remover pacotes excluídos da árvore da nova versão, saltar o download de pacotes de línguas indesejadas, …

Durante muito tempo mantive meu espelho do current com o wget e muita paciência, checando diretório por diretório, o que fica e o que sai do current. Filizmente, o Slackware mantém o arquivo FILELIST.TXT, com uma listagem completa de todos os pacotes e arquivos presentes em sua árvore, o que simplifica muito a automação da manutenção de um espelho.

O aplicativo Slackmirror é um programa em bash script que venho desenvolvendo alguns a anos, cujo papel fundamental é manter uma cópia atualizada do slackware-current bem como de outras versões do Slackware e seus derivados, como o Slamd64 e o Bluewhite64.
» Read more: Mantendo espelhos do Slackware com o Slackmirror

Selecionando Runlevel no Slackware

Abril 8th, 2008

O Slackware e seus derivados, como o Slamd64, são ótimos opções de distribuições, principalmente para aqueles que não se canção de investigar seu hardware e se divertem com isto, como vem sendo o meu caso a quase 14 anos.

No entanto, algumas tarefas, quando muito solicitadas, podem se tornar extremamente tediosas, como tem ocorrido no caso da configuraćão de meu novo notebook. A simples tarefa de alterar o runlevel do boot da máquina, em meio a diversos teste que tenho feito, extrapolaram minha tolerância.

A ferramenta que vou apresentar aqui, é o setrunlevel. Um aplicativo que fiz para alterar o runlevel, editando o /etc/inittab e/ou executando o comando telinit. O setrunlevel é um aplicativo em bash shell, que pode operar tanto no modo interativo, quanto não interativo. » Read more: Selecionando Runlevel no Slackware

Sorteio

Fevereiro 28th, 2008

Este script nasceu no segundo ENCASOFT (Encontro Capixaba de Software Livre), realizado em Colatina-ES. Na ocasião estava assistindo a uma palestra, enquanto preparava um Script Shell para realizar o sorteio entre os nomes dos inscritos no encontro. Os nomes sorteados eram presenteados com brindes fornecidos pelos colaboradores do encontro.

» Read more: Sorteio

Raízes de uma equação de segundo grau

Fevereiro 27th, 2008

Como professor de Física, uma das operações mais comuns é a resolução se equações de segundo grau. Embora seja bem simples, a repetição constante deste cálculo acaba se tornando tedioso e gastando um tempo desnecessário.

Uso isto geralmente quando estou preparando as provas, montando gabaritos. Para processo matemáticos mais extensos, geralmente utilizo ferramentas mais adequadas como o Scilab ou o Octave.

» Read more: Raízes de uma equação de segundo grau

Senhas Aleatórias

Fevereiro 26th, 2008

Volta e meia tenho que gerar senhas aleatórias e em algumas vezes, existe alguma limitação de “caracteres”, como senhas decimais, hexadecimais, alfanuméricos sem símbolos, …

Geralmente recorro a soluções diversas encontradas pela rede, mas na última vez que tive que gerar uma senha hexadecimal, achei que já era hora de criar uma solução personalizada.

» Read more: Senhas Aleatórias

Gerenciamento de Frequência do Notebook

Fevereiro 17th, 2008

Aproveitando o período de férias experimentei compilar os quase 1GB de pacotes do Gnome. O processo foi bem demorado, colocando o notebook em alta atividade com a temperatura beirando os 70°C. Sempre que observava temperaturas desta ordem reduzia, manualmente, a frequência da CPU. Depois de algumas horas de compilação resolvi criar um Script Shell para automatizar o controle.

Neste texto vou apresentar como implementar um Gerenciador de Frequência da CPU Personalizado, com simples comando de leitura e escrita pelo Shell.

» Read more: Gerenciamento de Frequência do Notebook