Caso sejam executados pelo root, os scripts podem também alterar arquivos de configuração do sistema, modificando entradas existentes ou incluindo novas configurações. O comando mais usado para fazer substituições é o sed. Para simplesmente adicionar linhas no final do arquivo, você pode usar o echo, o mesmo comando que usamos para escrever mensagens na tela.
Por exemplo, um erro comum ao acessar partições do Windows formatadas em NTFS é a partição ser montada com permissão de leitura apenas para o root. Você só consegue ver os arquivos abrindo o gerenciador de arquivos como root, o que é desconfortável.
Isto acontece porque o default do mount é montar partições NTFS e FAT com permissão de acesso apenas para o root. Para que outros usuários possam visualizar os arquivos, é necessário montar incluindo a opção “umask=000“.
A tarefa é relativamente simples, basta abrir o arquivo “/etc/fstab” e adicionar a opção na linha referente à partição.
Ao invés de:
Ficaríamos com:
umask=000 0 0Até aí tudo bem. O problema é que este parâmetro pode ser usado apenas em partições FAT ou NTFS. Se você usar em partições formatadas em ReiserFS ou EXT, elas não montam.
Ou seja, ao fazer isso via script, precisamos primeiro ter certeza de que a partição está formatada em NTFS, antes de alterar o “/etc/fstab”.
Uma forma de fazer isto é verificando a saída do comando “fdisk -l“, que mostra detalhes sobre as partições, como em:
Disk /dev/hda: 20.0 GB, 20003880960 bytes 255 heads, 63 sectors/track, 2432 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/hda1 * 1 401 3221001 7 HPFS/NTFS /dev/hda2 402 1042 5148832+ 83 Linux /dev/hda3 1116 2432 10578802+ 5 Extended /dev/hda4 1043 1115 586372+ 83 Linux /dev/hda5 1116 1164 393561 82 Linux swap / Solaris /dev/hda6 1165 2432 10185178+ 83 Linux
Podemos então usar o grep para filtrar a saída e carregar o resultado dentro de uma variável, de modo que ela contenha alguma coisa apenas se a partição testada estiver formatada em NTFS, como em:
Note que aqui estamos usando três comandos diferentes, ligados por pipes. Esta é uma prática comum na hora de filtrar a saída de comandos, já que é difícil chegar a um único comando que faça de uma vez tudo o que você precisa. Neste exemplo, o “grep hda1” vai remover todas as linhas, deixando apenas a linha referente à partição “/dev/hda1”. O “grep NTFS” verifica a linha e deixa-a passar apenas se a partição estiver formatada em NTFS, visto que, caso ela esteja formatada em outro sistema, a string com a identificação do sistema de arquivos será outra.
Usamos em seguida uma função que verifica se a variável é não nula (-n). Por causa dos dois comandos do grep, ela só conterá algum texto se o /dev/hda1 estiver formatado em NTFS. Usamos então um if com o comando do sed para alterar a linha no “/etc/fstab” caso positivo:
if [ -n "$winntfs" ]; then # O gigantesco comando abaixo forma uma única linha:sed -e 's/\/dev\/hda1 \/mnt\/hda1 auto noauto,users,exec 0 0/\/dev\/hda1 \/mnt\/hda1 auto noauto,users,exec,umask=000 0 0/g' /etc/fstab > /tmp/fstab2rm -f /etc/fstab; mv /etc/fstab2 /etc/fstab fi
Veja que a linha do sed é um pouco longa. A sintaxe básica para fazer substituições é:
Ele sempre gera um novo arquivo com as alterações, por isso depois do comando você ainda precisa remover o arquivo original e renomear o novo arquivo. Caso dentro da string de texto a substituir existam barras ou caracteres especiais, use barras invertidas (\) como no exemplo, para demarcá-los. As barras invertidas indicam que o caractere seguinte não deve ser interpretado.
O comando “sed -e ‘s/texto/novo-texto/g’ arquivo > novo-arquivo” que vimos, simplesmente substitui todas as instâncias da palavra “texto” por “novo-texto”. Você precisa certificar-se que a palavra só existe dentro do contexto que imagina, caso contrário, o comando pode facilmente causar acidentes. O ideal é que você seja sempre o mais específico possível.
Para deletar uma linha, use o comando “sed -e ‘/texto/D’ arquivo > novo-arquivo, como em:
O sed suporta também alguns caracteres especiais. O “^”, por exemplo, indica o início da linha. Para remover todas as linhas que começam com “#” (ou seja, linhas com comentários), use:
Note que precisei incluir uma barra invertida antes do “#”. Para remover todas as linhas em branco de um arquivo, use:
É possível também combinar vários comandos do sed usando o pipe, fazendo com que a saída de um passe também pelo outro antes de ser escrita no arquivo final. Para remover todas as linhas com comentários e todas as em branco, o comando seria:
Para eliminar espaços repetidos num arquivo (útil caso você queira filtrar alguma informação usando o cut):
Para substituir todos os espaços por quebras de linha (representadas pelo “\n” dentro do sed):
Para remover todas as quebras de linhas de um arquivo, fazendo com que tudo fique numa única linha (o que pode ser útil para facilitar a localização de determinadas informações, que originalmente estavam em várias linhas separadas), use esta função inventada pelo Thobias Salazar:
Você pode usá-la junto com a função sed ‘s/^/ /’, que adiciona um caracter no início de cada linha. Ao usar esta função (‘s/^/ /’), você pode substituir o espaço entre a segunda e terceira barra por outro caracter, ou conjunto de caracteres, como em sed ‘s/^/\&\&/’. Veja um exemplo de uso dos dois combinados, que formata o arquivo “.synergy.conf” (usado pelo Synergy, que vimos no capítulo 2):
section: screens kurumin: semprao: end section: links semprao: right = kurumin kurumin: left = semprao end section: aliases kurumin: 192.168.1.102 end
O sed, aliado ao grep, pode ser usado também para criar scripts inteligentes, que verificam a configuração do sistema e, se necessário alteram as linhas necessárias.
Por exemplo, para instalar o FreeNX server no Debian, seguindo o tutorial que publiquei no Guia do Hardware (https://www.hardware.com.br/tutoriais/usando-freenx-server-atualizado/), é necessário adicionar uma linha no “/etc/apt/sources.list”, com o repositório do Kanotix que possui os pacotes. Estes pacotes possuem algumas dependências do Unstable, de forma que o sources.list precisa conter também a linha correspondente.
Este é o trecho do script do ícone mágico que escrevi para o Kurumin, que verifica e altera o arquivo caso necessário:
# Verifica se o sources.list contém entradas para o unstable, # se não tiver adiciona: unstable=`sed '/^$/d' /etc/apt/sources.list | sed '/#/d' \ | grep "unstable main contrib"`if [ -z "$unstable" ]; thenecho "deb https://ftp.us.debian.org/debian unstable \ main contrib non-free" >> /etc/apt/sources.list remover="1"fi# Adiciona o repositório do freenx kano=`sed '/^$/d' /etc/apt/sources.list \ | sed '/#/d' | grep "project/kanotix/unstable/"`if [ -z "$kano" ]; thenecho 'deb https://debian.tu-bs.de/project/kanotix/unstable\ / ./' >> /etc/apt/sources.list removerkano="1"fi# Instala o freenx a partir do unstable do Kano apt-get update apt-get install -t unstable freenx nxsetup --install --setup-nomachine-key # Remove o unstable e/ou o repositorio do kano, se adicionado:if [ "$remover" = "1" ]; thenrm -f /tmp/sources.listsed -e '/deb http:\/\/ftp.us.debian.org\/debian unstable main contrib non-free/D' \ /etc/apt/sources.list > /tmp/sources.listrm -f /etc/apt/sources.list cp /tmp/sources.list /etc/apt/sources.list apt-get updatefiif [ "$removerkano" = "1" ]; thenrm -f /tmp/sources.listsed -e '/deb http:\/\/debian.tu-bs.de\/project\/kanotix\/unstable\/ \.\//D' \ /etc/apt/sources.list > /tmp/sources.listrm -f /etc/apt/sources.list cp /tmp/sources.list /etc/apt/sources.list apt-get updatefi
Logo no início do script são definidas duas variáveis, “unstable” e “kano” que são usadas para verificar se as linhas dos repositórios de que o script precisa estão ou não disponíveis no script. Esta informação é usada para decidir se se elas devem ser adicionadas ou não.
Localizar linhas no arquivo pode ser um pouco complexo. Como explicar para o script que ele deve ignorar a linha caso esteja comentada e como fazer ele ignorar pequenas variações nas linhas (como os códigos de país nas linhas dos repositórios do Debian)?
Prevendo isso, estou usando um “super pipe”, que usa dois comandos do sed para remover as linhas em branco (sed ‘/^$/d’), as linhas comentadas (sed ‘/#/d’) e em seguida o grep para filtrar apenas a linha que estou procurando. Para tornar o script mais flexível, faço a busca por apenas parte da linha, isso evita que a função deixe passar uma entrada similar, mas com outro mirror:
| grep “unstable main contrib”`
Caso as variáveis estejam vazias (-z), significa que as linhas não existem no arquivo. Neste caso, entram em ação as funções que coloco em seguida, que adicionam as linhas necessárias e criam mais duas variáveis (“remover” e “removerkano”) que são usadas para que o script “lembre” que fez as alterações e remova as linhas no final, deixando o arquivo da forma como estava originalmente.
A função para remover as linhas usa novamente o sed, desta vez numa sintaxe mais simples, que simplesmente deleta as linhas (sed -e ‘/texto/D’) anteriormente adicionadas. O sed não é capaz de salvar as alterações diretamente no arquivo, por isso é sempre necessário salvar num arquivo temporário e depois substituir o arquivo original por ele.
Você pode ver mais dicas e exemplos do uso do sed na página do Aurélio: https://aurelio.net/sed/.
Esta postagem foi modificada pela última vez em 25/09/2010 15:53