PostHeaderIcon Reduzindo o tamanho de arquivos PDF através da linha de comando.

Recentemente, precisei submeter uns arquivos no formato PDF para um site. Entretanto, o sistema tinha uma limitação com relação ao tamanho dos arquivos PDF que deveriam ser submetidos. Tentei utilizar algumas opções do editor de textos que eu havia utilizado para criar os arquivos PDF com tamanho menor, mas, infelizmente, não obtive sucesso. Ainda que essa solução funcionasse, eu deveria repeti-la, pelo menos, 15 vezes, manualmente. Foi nesse momento que resolvi encontrar uma nova solução através através do "sabre de luz" de todo administrador e usuários mais avançados do mundo Linux: a linha de comando.

A solução pode ser feita através do Ghostscript, um antigo e bem poderoso pacote de ferramentas que já vem instalado em muitas distribuições Linux. Para reduzir um arquivo PDF, usando o gs, utilizei o seguinte comando:

$ gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen \

     -dNOPAUSE -dQUIET -dBATCH \ 

     -sOutputFile=ArquivoReduzido.pdf ArquivoOriginal.pdf

Em poucos instantes, você tem o seu arquivo PDF com o tamanho significativamente menor. O mais interessante, entretanto, para evitar um trabalho repetitivo, é combinar esse comando em um pipe para, por exemplo, converter diversos arquivos PDF de uma única vez. Por exemplo, considerando que no diretório /tmp/PDFs estão todos os arquivos com extensão ".pdf" a serem reduzidos que devem ser armazenados no diretório /tmp/PDFzinhos, basta executar a seguinte linha de comando:

$ cd /tmp/PDFs ; ls *pdf |  xargs -t -i gs -sDEVICE … … … \

   -sOutputfile={}  /tmp/PDFzinhos/{}

(Substitua os "… … …" por todo o restante do comando gs mostrado anteriormente)

Pronto! Tudo devidamente reduzido de uma única vez!

Ainda é possível melhorar ainda mais o uso dessa linha de comando, incorporando-o a um script com diversos recursos legais. Entretanto, deixo isso como um exercício para vocês! :-)

Acho que é isso. Até a próxima!

PostHeaderIcon Removendo kernels antigos no Ubuntu.

Atualizar o kernel de seu Linux já foi uma tarefa complicada. Atualmente, o pacote de kernel e todas as suas dependências são atualizadas de maneira muito simples. Muitas vezes, basta que um alerta no seu ambiente gráfico apareça reportando que existem atualizações pendentes e pronto… tudo será atualizado, inclusive o kernel. 

Entretanto, uma atualização de kernel não substitui os pacotes das versões anteriores. Com o passar do tempo, seu sistema passa a ter um conjunto de versões mais antigas de kernel que já não são utilizadas e apenas consomem espaço. Recentemente, dei-me conta de que estava sem espaço no "/" de meu laptop. Ao investigar o que poderia ser descartado vi que existiam mais de 12 versões antigas de kernel. Uma simples consulta com dpkg foi suficiente para identificar isso:

# dpkg -l linux-image-*

A tarefa simples seria a de remover todos esses kernels antigos, um a um. Mas que trabalho tedioso seria fazer isso, não é mesmo? Obviamente, como um administrador de sistemas Linux, uma situação dessa logo desperta a vontade de resolver tudo isso de uma única vez, através da linha de comando e de um toque Jedi. Então, para quem está procurando algo parecido ou está passando pela mesma situação, aproveito o espaço para compartilhar a solução que representa, acima de tudo, uma excelente oportunidade para praticar o uso dos poderosos pipes presentes em todos os sistemas Unix. Os exemplos apresentados foram testados em um ambiente Ubuntu, entretanto com poucas modificações, pode ser utilizado em outras distribuições também.

O comando a seguir é suficiente para você ter uma relação que contenha apenas os nomes de todos kernels que estão instalados em seu sistema com exceção do kernel atual que está em execução no momento:

# dpkg -l linux-image-[0-9]* | grep -v $( uname -r) | awk '/^in/{print $2}'

O próximo passo é utilizar o próprio comando dpkg para remover os kernels que não estão mais em uso:

# dpkg -P $( dpkg -l linux-image-[0-9]* | grep -v $( uname -r) | awk '/^in/{print $2}' )

Quer entender o que foi feito em cada comando? Bem, uma dica é executar o primeiro comando, depois executá-lo com o primeiro pipe e o próximo comando e assim por diante.

Bem, acho que é isso. Até a próxima!

PostHeaderIcon Protegendo seu terminal de comandos do esquecimento…

Passo por aqui, dessa vez, para uma dica bem rápida e que, pra mim, é bastante útil. Não é raro encontrar mundo de TI afora terminais de comandos abertos em servidores (alguns deles bem importantes). Perdi as contas das vezes em que me deparei com acessos de root dados "de graça" em servidores Linux simplesmente após pressionar qualquer coisa no teclado que tirasse o monitor do modo de economia de energia para revelar uma sessão logada. Para ambientes onde existe o ambiente gráfico, isso não é um problema tão sério já que a maioria deles trava a tela após um determinado perído de tempo sem uso. Mas, e o que fazer com relação àqueles servidores onde apenas o modo texto está disponível?

Uma dica muito simples para resolver essa questão é contar com um truque "Jedi" que existe no shell (bash e outras). Trata-se da variável especial  "TMOUT". Ela determina o número de segundos em que um terminal de comandos pode permanecer aberto, sem uso, antes que seja fechado automaticamente. Quer tentar? Pra isso, basta abrir um terminal de comandos qualquer e executar o seguinte comando:

$ export TMOUT=10

Em seguida, observe, com os próprios olhos que, passados 10 segundos de inatividade, o terminal simplesmente fecha! Interessante, não?

Entretanto, como de costume, a execução do comando anterior afeta apenas o terminal onde ele foi executado. Para fazer com que essa configuração seja feita para um usuário em todos os terminais de comandos abertos por ele, basta inserir o comando anterior, por exemplo, no arquivo ".bashrc" localizado dentro do diretório home do usuário. Ou ainda, para fazer com que todos os usuários estejam sujeitos à mesma configuração, pode-se inserir o comando em arquivos como o /etc/profile ou /etc/bash.bashrc.

Bem, acho que é isso… Até a próxima!

PostHeaderIcon Publicados os slides da palestra no FISL.

Entre os dias 25 e 28 de julho, aconteceu em Porto Alegre, mais uma edição do FISL (Fórum Internacional de Software Livre), o maior evento de software livre do País. Já fazia alguns anos que não conseguia participar do evento, entretanto, nessa edição, consegui estar presente novamente. Ao contrário das edições anteriores, o assunto de minha apresentação não foi relacionado à segurança e, sim, à administração de sistemas. A bola da vez foi compatilhar uma solução para construir um storage de baixo custo usando PCs comuns, Linux e software livre. A ideia veio depois dessa ser uma solução criativa que encontramos para um projeto desenvolvido dentro da empresa para qual trabalho.

Como prometido, publico por aqui os slides que utilizei ao longo da apresentação para aqueles que estavam presentes e para aqueles que não puderam participar mas tem interesse no assunto. Os slides podem ser encontrados na seção de PALESTRAS RECENTES do site.

Em tempo, gostaria de deixar por aqui registrado o meu agradecimento a todos que estiveram presentes na palestra. Recebi excelentes e gratificantes feedbacks que servem, evidentemente, como um motor propulsor para novas e criativas aventuras técnicas! Bem, acho que é isso. Até a próxima!

PostHeaderIcon Storage iSCSI com Linux e software livre: assunto para o FISL 13.

Depois de alguns anos sem conseguir estar presente no FISL, esse ano retomo minha participação no evento. Nessa oportunidade, ao contrário dos anos anteriores, estarei falando sobre um tema muito mais relacionado à administração de sistemas do que de segurança. Fruto de um projeto que precisamos desenvolver para um cliente, essa solução, baseada em software livre, viabilizou a configuração de um storage que, apesar de ser bem simples, nos permitiu a implantação de um ambiente de cluster de alta disponibilidade tal qual estava previsto no início das discussões a respeito do projeto respeitando, entretanto, as restrições de investimentos.

A palestra está programada para as 14:00 na sala 41B (daemon) no dia 28/07. O restante da programação do FISL pode ser acessada por AQUI.  Serão quatro dias de boas discussões sobre soluções em software livre. 

A seguir está uma descrição da palestra. Nos vemos por lá?

Criando um Storage iSCSI com PCs, Linux e Software Livre! Que tal?

Muitos ambientes de alta disponbilidade (e.g. clusters) necessitam de storages como um meio de armazenamento compartilhado em suas arquiteturas. Na verdade, esses equipamentos são peças fundamentais nas arquiteturas mais tradicionais. Outras soluções de infraestrutura de software também precisam desses equipamentos. Existem, certamente, diversas disponíveis no mercado. Entretanto, mesmo os storages mais simples costumam requerer um valor de investimento que, muitas vezes, está além das possibilidades financeiras de diversas organizações. Por outro lado, utilizando apenas PCs convencionais e ferramentas de software livre é possível construir uma solução de storage iSCSI com interessantes recursos de alta disponibilidade capaz de servir como uma alternativa de baixo custo e de qualidade. A solução consiste na utilização de uma implementação livre e estável do padrão iSCSI no lado do servidor storage e de seus clientes. Além disso, a solução ainda conta com outros recursos em software livre que ajudam a compor a camada de alta disponibilidade. Do ponto de vista dos "clientes" que o acessam, esse "storage" é como qualquer outro equipamento iSCSI de mercado, o que torna a utilização dessa solução transparente àqueles que já conhecem esses appliances. Essa é, portanto, uma alternativa interessante para ambientes onde existem restrições financeiras para a aquisição de equipamentos como os custosos storages e onde não são necessários os recursos mais avançados que esses produtos oferecem sem, entretanto, abrir mão de uma razoável camada de alta disponibilidade. 

PostHeaderIcon A lição nossa de cada dia… quando o espaço não é tudo.

Seu telefone toca durante a madrugada. Um dos sistemas mais importantes para um cliente parou subitamente de funcionar. É preciso tomar uma ação imediata. Ao tentar verificar qual foi o problema, uma rápida olhada nos logs do sistema revela algo que parece comum e, aparentemente, fácil de resolver: problemas no sistema de arquivos com a messagem “no space left on device“. Pronto… logo mais você estará com o problema resolvido e dormindo novamente. Na certeza da vitória, você executa um df, mais ou menos dessa maneira:

# df -m

Uma rápida passada de olho procurando confirmar o óbvio: alguma partição está com 100% de ocupação. Diante disso, aumenta-se o tamanho da partição ou move-se alguns arquivos para outras partições… Mas, para sua surpresa e para a infelicidade de sua noite de descanso, nenhuma das partições do sistema apresenta ocupação máxima:

[root@amhsnode01-br ~]# df -m
Filesystem           1M-blocks      Used Available Use% Mounted on
/dev/sda1                 9920      3433      5975  37% /
/dev/sda2                  961        20       892   3% /tmp
/dev/sda3                 3968       320      3444   9% /var
/dev/sda4                  996        40       905   5% /boot

O nervosismo toma conta… mais telefones irão tocar em breve. Ainda em busca da verdade e sem saber no que acreditar, você monta o sistema de arquivos que provocou o problema e tenta criar um arquivo:

# touch /var/nightmare/teste

E a mensagem aparece novamente: “no space left on device“. E agora?

Read the rest of this entry »

PostHeaderIcon Como trocar a senha de um usuário em um shell script?

Vez em quando me deparo com amigos me perguntando como é possível, a partir de um shell script, alterar a senha de um usuário. Bem, então, acho que, apesar de ser uma dica bem simples, acho que publicá-la por aqui pode ser uma boa forma ajudar outros amigos perdidos na imensidão da Internet que, eventualmente, estejam precisando de uma solução rápida para esse problema.

Bem, existem diversas maneiras de lidar com essa questão. Entretanto, comento por aqui uma alternativa que, em minha opinião, é uma das mais simples de entender, utilizar e, principalmente, lembrar quando for necessário. Para ilustrar melhor o problema: suponha que você está desenvolvendo algum shell script que cria alguns usuários e nesse processo é necessário atribuir uma senha (aleatória ou não) a eles. Supondo que o username e a senha a ser atribuídas estão armazenados nas variáveis $MYUSER e $MYPASSWORD, respectivamente, basta inserir em seu shell script algo semelhante ao seguinte comando:

MYUSERNAME="fulano"
MYPASSWORD="novasenha"
...
echo "$MYPASSWORD" | passwd --stdin "$MYUSERNAME"

Pronto! Simples, não? Bem, acho que é isso. Até mais.

PostHeaderIcon Shell script: como fazer um loop até que uma tecla seja pressionada?

Recentemente, um amigo me mandou um email com uma dúvida: ele precisava desenvolver um shell script que ficasse executando uma determinada tarefa até que uma tecla pré-estabelecida fosse pressionada. Por imaginar que essa pode ser a necessidade de muitos outros sysadmins, usuários e desenvolvedores que trabalham com o mundo GNU/Linux, resolvi compartilhar essa rápida discussão por aqui.

Bem, existem várias maneiras para resolver esse problema e resolvi indicar uma das formas que julgo ser de fácil e rápido entendimento. O ponto chave é utilizar o comando read. Vejamos o exemplo a seguir:

#!/bin/bash
while read MyKey; do
        if [ "$MyKey" == "p" ]; then
                echo "Tecla escolhida foi pressionada. Saindo do loop."
                break
        fi

        # // Inclua aqui comandos a serem executados...
        # // ...enquanto a tecla nao e pressionada
        echo "Minhas tarefas estao sendo executadas"

done
echo "Fim."

Bem, isso não parece resolver o problema, certo? Isso porque as tarefas devem ficar sendo executadas enquanto uma tecla pré-determinada (nesse caso, “p”), não for pressionada. Por outro lado, no exemplo anterior, as tarefas serão executadas apenas quando uma tecla qualquer, que não seja o próprio “p”, for pressionada. Isso ocorre porque o comando “read” ficará aguardando indefinidamente que o usuário digite alguma tecla que, por sua vez, é inserida na variável MyKey . Bem, definitivamente, não é disso que precisamos, certo?

Poucas pessoas sabem, mas o comando read não precisa ficar aguardando infinitamente alguma entrada do usuário. Com o parâmetro “-t <seg>” você pode indicar quantos segundos o comando irá ficar aguardando para que algo seja digitado. Caso o tempo indicado, em segundos, expire e nada seja digitado, o comando encerra sua execução. Sabendo disso, algumas pequenas mudanças nos farão chegar onde precisamos:

#!/bin/bash
while true ; do          
        read -n 1 -t 1 MyKey
        if [ "$MyKey" == "p" ]; then
                echo "Tecla escolhida foi pressionada. Saindo do loop."
                break
        fi

        # // Inclua aqui comandos a serem executados
        # // ...enquanto a tecla nao e pressionada
        echo "Minhas tarefas estao sendo executadas"
done
echo "Fim."

Feito, não? Entretanto, para ser um pouco mais caprichoso com o exemplo, ainda é possível alterar um “pouquinho  mais” o exemplo:

#!/bin/bash
INTERVALO=2 
while true ; do          
        read -s -n 1 -t $INTERVALO MyKey
        if [ "$MyKey" == "p" ]; then
                echo "Tecla escolhida foi pressionada. Saindo do loop."
                break
        fi

        # // Inclua aqui comandos a serem executados...
        # // ...enquanto a tecla nao e pressionada
        echo "Minhas tarefas estao sendo executadas"
done
echo "Fim."

Duas pequenas mudanças, certo? A primeira, muito básica, consiste em colocar o intervalo de tempo do read em uma variável. Dependendo do script, isso pode ajudar para mudar o comportamento sem entrar muito no código. A segunda, igualmente simples, consiste na adição do parâmetro “-s” que faz com que a tecla pressionada pelo usuário não seja impressa no terminal. Puro capricho… :-)

Acho que é isso. Até a próxima!

PostHeaderIcon Campus Party BR 5: “Universidade e Software Livre”.

A Campus Party 5 já começou aqui pelo Brasil, em São Paulo, desde o dia 06/02/2012. Além de ser uma excelente oportunidade para rever amigos de longa data, muitas palestras e discussões interessantes estão sendo feitas ao longo desses últimos dias. Novas tecnologias, software livre, produtos, soluções, experiências estão, constantemente nas pautas. Falando nisso, fui convidado para participar de uma mesa redonda com o tema de “Universidade e Software Livre“, um assunto que possui importância fundamental, em minha opinião, quando se trata de criar um processo nacional de desenvolvimento tecnológico consistente.

Falei a respeito desse assunto pela primeira vez em alguns eventos há alguns anos, mesmo período em que publiquei dois pequenos posts com algumas opiniões a respeito do assunto. Com isso, para adiantar a discussão, aproveito a oportunidade para publicá-los por aqui novamente:

Estarão participando da mesa redonda o Prof. Dr. Pedro Rezende (UnB), o Rodrigo Padula (NCE/UFRJ), o José Honorato (mediador) e esse que vos escreve.

A mesa redonda deve ocorrer no próximo sábado, dia 11/02/2012, às 14:30. Nos vemos por lá?

Mais informações, AQUI.

PostHeaderIcon Quando a ajuda cai do “shell”…

Muitos administradores de sistemas, desenvolvedores e até usuários (mais avançadas) de GNU/Linux (e outros tipos de Unix, na verdade) costumam lidar com a famosa “tela preta” por horas todos os dias. E, como não poderia ser diferente, mudar de diretórios é uma tarefa executada dezenas ou centenas de vezes em uma simples jornada de trabalho. Com isso, errar o caminho do diretório é algo bem comum e que, além de fazer você perder tempo, pode prejudicar sua paciência!

Uma das formas de facilitar sua vida no poderoso mundo da “tela preta” é o próprio recurso do auto completion, presente em shells com o bash. Outro truque bem simples e interessante, mas deconhecido por muitos, é comando shopt. Com ele, pode-se pedir uma ajuda da shell para completar seus comandos “cd” para mudar de diretório quando há apenas um pequeno erro de digitação.

Por exemplo, suponha que ao tentar entrar no diretório /tmp, vc execute o seguinte comando:

$ cd /tmx

Obviamente que você receberá uma mensagem de que esse diretório (/tmx) não existe. Entretanto, tente executar o comando shopt dessa maneira:

$ shopt -s cdspell

Em seguinda, tente executar o comando “cd /tmx” e confira que, mesmo tendo errado o caminho, você estará dentro do diretório pretendido, ou seja, o /tmp. Se você quiser que todas os seus terminais de comandos sejam executados já com essa opção, basta inserir o comando “shopt -s cdspell” no arquivo .bashrc ou .bash_profile (conforme sua distribuição Linux ou versão de Unix).

Antes de terminar, logicamente que o título desse pequeno post é completamente baseado nas “peripécias criativas” de meu grande amigo e mestre do shell Júlio Neves. Por fim, como se pode ver, mesmo no mundo da “tela preta”, às vezes, a ajuda cai do “shell”. Até a próxima!