Configurando o locale no Ubuntu

É um problema comum ao configurar um novo servidor com Ubuntu, descobrir que não há um locale válido configurado, ou descobrir que o locale padrão não é o que você desejava. Os sintomas comuns de um sistema sem um locale válido são as seguintes mensagens:

locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory

Ou essa outra, bem mais assustadora:

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
   LANGUAGE = (unset),
   LC_ALL = (unset),
   LC_CTYPE = "pt_BR.UTF-8",
   LANG = "en_US.UTF-8"
   are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

Os sintomas de um locale diferente do que você gostaria são mensagens em algum idioma estranho.

Como corrigir? Vou postar aqui, porque esse arquivo fica num local muito inusitado, em minha opinião. Não está em /etc. Edite, como root, o arquivo:

/var/lib/locales/supported.d/local

E coloque os locales que você quer que o sistema suporte. A maioria dos usuários brasileiros vai se dar bem com esse conteúdo:

pt_BR ISO-8859-1
pt_BR.UTF-8 UTF-8

No meu caso, como faço questão de trabalhar exclusivamente com Unicode, eu deixo esse arquivo assim:

pt_BR.UTF-8 UTF-8

Em seguida rode:

sudo dpkg-reconfigure locales

Isso deve resolver o problema.

Meu ambiente de trabalho em 7 itens

O Mike me convidou, então lá vai:

1. Ubuntu

O sistema operacional que simplesmente funciona. Meu notebook tem Ubuntu, o da minha mulher e os dos meus filhos também. Todos tem o Windows OEM em dual-boot. Nem me lembro quando foi a última vez que vi alguém bootar o Windows lá em casa. Aqui na Visie o Ubuntu também parece ser o sistema predileto de todo mundo que não tem um Mac 😉

Sem brincadeira, se você desenvolve para um sistema Unix-like, deveria usar um. Você vai ter o mesmo modelo de permissões, a mesma estrutura de arquivos e as mesmas ferramentas na sua máquina e na hospedagem. Você vai ter shell script. Um dia desses resolvemos um problema em um projeto criando um link simbólico para um arquivo. Essa solução roda em nossos servidores e em nossos desktops.

2. Git

Ainda encontro muitas empresas por aí que não usam controle de versão. Pode parar de rir, estou falando sério. Eu não entendo como alguém pode escrever software sem um bom sistema de controle de versão distribuído.

3. web2py

O framework de desenvolvimento web mais produtivo que eu já achei.

4. Vim

Vim não é fácil, e deve ser mantido fora do alcance de crianças e animais domésticos. Mas é o editor de código mais rápido do planeta. Extremamente poderoso, indispensável para o bom programador.

5. Firefox e Firebug

O desenvolvimento de HTML, CSS e Javascript se divide em duas eras: antes e depois da Firebug.

6. OpenDNS e Dnsmasq

Nós até conseguimos comprar boas conexões aqui no Brasil. Mas os serviços de DNS de todos os provedores que eu conheço são uma piada.

7. Terminator

Com o Terminator posso dividir uma janela em vários terminais, em abas. Para quem usa vim e muito shell, é uma mão na roda.

E eu vou convidar:

Diego Eis, Ederson Peka, Luciano Motta, Mauro Baraldi, Leandro Lima e Pedro Rogério.

Codificar vídeo no Linux para iPod, iPhone, Android, PSP, etc? Transmageddon

O vídeo possui duas ferramentas fantásticas para a conversão de vídeo: ffmpeg e mencoder. Mas são ferramentas de linha de comando e nada fáceis de usar. Veja, por exemplo, como ripar DVDs para DivX com mencoder. Se a origem, ao invés de um DVD, for um arquivo mpeg, isso tudo muda bastante. Se a saída, ao invés de DivX, for mp4, muda bastante também.

Conheci recentemente o Transmageddon, ferramenta fantástica. Veja um screenshot:

Transmageddon

Se você clica em “Pré-definições”, por exemplo, veja a lista que aparece:

Transmageddon

Serve para quase tudo o que você pode querer fazer convertendo vídeo. Sem dor. Vale a pena experimentar.

O Linux também fala

Há um tempo eu ensinei aqui como fazer o Mac falar. O Linux também faz. Instala aí:

$ sudo apt-get install espeak

Daí é só mandar:

$ espeak "Luke, I am your father."

E fala português também:

$ espeak -v pt "Luke, eu sou seu pai."

Com -f arquivo.txt, ele lê o texto de um arquivo. Com -w arquivo.wav, ele salva o áudio num arquivo. E pode ser comandado via ssh.

Consegue imaginar utilidades para isso?

Exportando MySQL para CSV

Criei agora um pequeno script para resolver um problema meu, um exportador de base de dados MySQL para arquivos CSV. Resolvi compartilhar:

MySQL2CSV

Para baixar, você vai precisar do git. No Ubuntu, para instalar, faça:

$ sudo apt-get install git-core

Depois, para baixar:

$ git clone git@github.com:elcio/mysql2csv.git

Isso vai criar a pasta mysql2csv, com o script dentro. Você pode copiá-lo para a pasta /usr/local/bin/ e dar permissão de execução se for usar com muita freqüência:

$ cd mysql2csv
$ sudo cp mysql2csv.py /usr/local/bin/mysql2csv
$ sudo chmod +x /usr/local/bin/mysql2csv

Se fizer isso, vai poder chamar, em qualquer diretório:

$ mysql2csv host user passwd dbname

Rodando comandos do sistema operacional com cache no Python

Código simples, mas que pode ser útil para alguém não ter que escrevê-lo de novo (arquivo runcached.py):

import os,time
cachepath='cache'
timeout=360
 
def runcached(cmd):
  filename=os.path.join(cachepath,str(hash(cmd)))
  if os.path.isfile(filename):
    if time.time()-os.path.getmtime(filename)<timeout:
      return open(filename).read()
  t=os.popen(cmd).read()
  open(filename,'w').write(t)
  return t

A função runcached roda comandos do sistema operacional, e faz cache do resultado por 6 minutos. Para alterar o tempo do cache, basta mudar a variável timeout. Por exemplo, para cachear por 10 horas:

import runcached
runcached.timeout=36000
r=runcached('lynx --source http://www.tableless.com.br')

Navegação rápida com o Google Public DNS

Uma coisa que sempre me espantou é a ineficiência dos servidores de DNS dos provedores de hospedagem brasileiros. Já testei ADSL, cabo coaxial, 3G e, aqui em São Paulo, de maneira geral as conexões são boas. Mas como o servidor de DNS dos provedores é ruim, a navegação é muito lenta.

Eu vinha usando OpenDNS, cuja performance é muito boa. Mas hoje resolvi testar o Google Public DNS. Deixa o OpenDNS no chinelo!

Como o Google conseguiu isso? Um mega sistema de cache, com cobertura global, e um inovador sistema de prefetching. Se você não está usando ainda, vale a pena testar.

Para facilitar a vida dos usuários de Linux, segue meu /etc/resolv.conf:

nameserver 8.8.8.8
nameserver 8.8.4.4

Sim, são esses IPs mesmo 😉 Não é fantástico?

Sobre Windows, Linux, paixões e times de futebol

Discussões sobre o melhor sistema operacional, o melhor navegador ou a melhor linguagem de programação tendem a entrar em loop infinito. Cada um dos lados parece achar o outro um completo idiota por não se convencer de suas opiniões.

Semana passada troquei algumas mensagens com o René de Paula que me fizeram pensar bastante sobre o assunto. O René provavelmente não me conhece, mas eu tenho aprendido muito com ele nos últimos anos, principalmente em seu podcast, o Roda e Avisa. E esse post não é um desabafo “estou chateadinho”. Estou citando o nome do René porque a conversa se deu no Twitter, ou seja, em público, e realmente me fez pensar.

O René recomendou esse artigo da ZDNet, analisando um estudo de segurança dos navegadores web. O artigo começa apresentando os resultados do estudo, em que o Internet Explorer ganha de lavada, e segue explicando porque, na opinião do autor, o estudo patrocinado pela Microsoft é tendencioso e irrelevante.

Respondi ao René dizendo que concordava com o artigo que ele havia indicado, que realmente o estudo era tendencioso. E usei a frase “o rei está nu.” Para mim, a crônica da roupa nova do rei é uma excelente metáfora para a situação. Ele me respondeu que havia visto meu blog e que achava que havia um “viés oculto” em tudo o que eu dizia. Em seguida twittou sobre o fato de as pessoas tratarem essas discussões como se fossem sobre times de futebol. Isso me fez pensar um bocado.

Eu gosto de, numa discussão, ouvir o outro lado. Também gosto muito de lógica. Se tem uma coisa que eu vou defender numa discussão, mais do que meu time de futebol, é o bom uso da lógica. Tento nunca ser irrazoável. Sei que todos somos tendenciosos, mas sempre tento ser mais imparcial que a média.

Talvez seja o fato de a discussão ter acontecido no Twitter, meio pouco propício, mas confesso que fiquei muito preocupado com a impressão que o René teve. Quem me conhece, sabe, trabalho com Linux, Windows ou Mac, sem rabo preso, escolhendo sempre o jeito mais simples de resolver cada problema.

Cada cabeça, uma sentença

Em primeiro lugar, não há um sistema operacional “melhor” e outro “pior”. Há um “melhor para você”. O fato de aquele seu amigo usuário de Windows não ter enxergado ainda que o Linux é o melhor sistema operacional do mundo talvez seja porque, para o perfil de uso dele, o Windows seja realmente o melhor sistema operacional.

Dificilmente eu tento convencer alguém a usar exclusivamente Linux. Sempre tento convencer as pessoas a experimentar. Se o sujeito me diz que é um heavy gamer, por exemplo, recomendo o uso de Windows. Sei, o Wine está muito evoluído e tal, mas se ele tem dinheiro para pagar as licenças e pode rodar a versão mais nova de cada jogo no ambiente em que ele foi feito para rodar, por que complicar?

Sim, não me esqueci, para certos perfis de uso, Mac OS X também é um sistema fantástico. Estou quase comprando um para minha mulher.

Existem, porém, padrões absolutos

O fato de não existir uma solução “bala de prata” e a paixão que costuma cercar essas discussões têm levado muita gente, principalmente programadores, a uma posição morna tão irrazoável quanto os extremos. É comum ouvir frases como “a melhor linguagem é aquele com a qual você sabe trabalhar” ou “a melhor ferramenta é a que resolve seu problema.”

Acredito sim que há casos de uso os mais variados. Mas, dentro de determinado caso de uso, há métricas objetivas que você pode usar para dizer o que é melhor. Falando em linguagem de programação, por exemplo, a melhor não é aquela que faz você se “sentir bem”. A não ser que programar para você seja só um hobby, a melhor é aquela que vai te permitir resolver mais rápido o problema do cliente, com a qualidade e a performance necessárias.

Dado um determinado problema do cliente, e uma determinada métrica de performance, deve ser possível apontar a melhor linguagem para essa situação.

Que problema seu software se propõe a resolver?

Se você é desenvolvedor de software, é importante entender isso. Você dificilmente vai encontrar uma oportunidade de desenvolver um produto que é o melhor para todo mundo. Não há unanimidades.

Você pode desenvolver algo que é o melhor para a maioria, pode achar uma minoria endinheirada, ou pode desenvolver algo legal para você mesmo e torcer para que haja gente parecido com você lá fora.

Mas, se você tentar ouvir todas as sugestões que receber e superar os concorrentes em absolutamente todos os perfis de uso, nunca vai terminar de desenvolver.

Mente aberta

Na Visie hoje temos 7 máquinas Windows, 6 Linux e 3 Macs. Sem contar as VMs, o ambiente de testes, e os servidores onde estão hospedadas as aplicações. Desenvolvedor, abra sua mente. Aprenda uma linguagem de programação nova, experimente outro sistema operacional, teste outra solução. Você vai aprender muito.

Aprenda Python, Ruby, Haskell ou Scala. Isso vai tornar você um melhor programador PHP, Java ou .Net. Desenvolva um projeto com uma banco de dados não relacional (estou usando MongoDB em um projeto.) Se você ama WordPress, faça alguma coisa com Joomla, e vice-versa. Tente outro framework, outro editor, outro jeito.

Sobre navegadores

No dia seguinte a essa conversa estive no escritório do W3C Brasil, assistindo ao Café com Browser com o pessoal do Internet Explorer.

Eles passaram boa parte do tempo falando sobre os recursos do navegador para o usuário final. Coisas como abas (oh!) e favoritos mais legais, webclips, processos independentes em cada aba, melhorias de performance e segurança. Tudo muito interessante mas, eu acho, apresentado para o público errado. Estávamos dentro do W3C, afinal de contas. Queríamos saber sobre as melhorias para o desenvolvedor.

Ao final, a palestra sobre melhorias para o desenvolvedor foi, para mim, parte surpreendente, parte decepcionante. Me surpreendi principalmente pela reação dos desenvolvedores no Twitter. Muita gente não conhecia as developer tools do IE8, ou os modos de compatibilidade, por exemplo. Quando foi apresentado o querySelector, muita gente twittou revoltada, porque a Microsoft estava “inventando um novo jeito proprietário de fazer as coisas”. Gente, o querySelector é uma recomendação do W3C (está em Working Draft, mas está lá.)

A parte decepcionante, expressei em minha pergunta:

Em suma, não tenho ódio da Microsoft ou de quem quer que seja. Não quero que o Internet Explorer suma do mapa. Ainda tenho projetos em ASP, VB e .Net, e sou feliz com isso. Só quero poder desenvolver uma vez só minhas aplicações. Quero não ter que cobrar do cliente pelo custo de fazê-la funcionar no Internet Explorer. Quero entregar mais rápido aplicações melhores, mais estáveis, com menos código.

Instalando o CouchDB e o Python-CouchDB no Ubuntu 8.10 (Intrepid)

Não a versão do repositório, mas a mais nova.

Só a sequência de comandos, que eu estou com pressa agora:

sudo apt-get install build-essential erlang libicu38 libicu-dev libmozjs-dev automake autoconf libtool help2man libcurl-ocaml-dev subversion python-setuptools
mkdir ~/src
cd ~/src
svn co http://svn.apache.org/repos/asf/couchdb/trunk couchdb
cd couchdb
./bootstrap && ./configure && make && sudo make install
sudo adduser --system --home /var/lib/couchdb --no-create-home --shell /bin/bash --group --gecos "CouchDB Administrator" couchdb
sudo chown -R couchdb /usr/local/var/lib/couchdb/
sudo chown -R couchdb /usr/local/var/log/couchdb/
sudo easy_install simplejson
sudo easy_install httplib2
sudo easy_install couchdb

Brincando com a API do twitter

Resolvi experimentar um pouco a Twitter API. É linda, do jeito que toda API deveria ser. É REST, muito fácil de entender e colocar para funcionar, e devolve dados em XML, JSON, RSS e ATOM.

Essa simplicidade permite interagir com a API usando ferramentas simples da linha de comando do Unix, como o wget e a cURL. Para nossos exemplos, vamos usar cURL. Se você usa Ubuntu, antes de começar faça:

sudo apt-get install curl

Para fazer um simples post, por exemplo, você pode digitar, em seu terminal:

curl -u seu_username:sua_senha -d status="Twittando do terminal. Aprendi com o Elcio: http://blog.elcio.com.br/brincando-com-a-api-do-twitter/" http://twitter.com/statuses/update.json

É isso mesmo, meninos e meninas, é só um post com autenticação, mais nada. RESTful, simples e elegante, deixar qualquer SOAP no chinelo. Inspirador para qualquer um que precise projetar uma API. Isso retorna dados em JSON. Se você quiser os mesmos dados em XML, ATOM ou RSS, basta mudar a extensão na url.

Agora vamos automatizar isso. Eu criei um arquivo /usr/local/bin/twitter com o seguinte conteúdo:

source $HOME/.twitter
curl -u $user:$password -d status="$@" http://twitter.com/statuses/update.json

Naturalmente, criei o arquivo como root e dei permissão de execução para todos os usuários. Agora, no diretório de cada usuário, basta criar um arquivo .twitter com o seguinte conteúdo:

user=seu_username
password=sua_senha

Pronto, tendo feito isso, qualquer usuário que tenha o arquivo .twitter em seu home pode twittar do terminal com:

twitter "Twittando do terminal, aprendi com o Elcio: http://blog.elcio.com.br/brincando-com-a-api-do-twitter/"

Simples e indolor, agora você pode automatizar suas twittadas com shell script. Pode, por exemplo, twittar toda vez que seu servidor baleiar, ou agendar twits com cron.

Search API

A Search API também é espetacularmente simples, dê uma olhada. Fiz a UPBox usando a Twitter Search API, por exemplo, com 22 linhas de código.

Fuja da complexidade

Abri o OpenOffice Writer, mandei gravar uma macro, escrevi “teste”, selecionei e pintei de vermelho. Olha o código gerado:

sub Main
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Text"
args1(0).Value = "teste"
dispatcher.executeDispatch(document, ".uno:InsertText", "", 0, args1())
rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:SelectAll", "", 0, Array())
rem ----------------------------------------------------------------------
dim args3(0) as new com.sun.star.beans.PropertyValue
args3(0).Name = "FontColor"
args3(0).Value = 16711680
dispatcher.executeDispatch(document, ".uno:FontColor", "", 0, args3())
end sub

Há muito código complexo por aí. Nesse caso, para invocar os métodos dos objetos do OpenOffice, é preciso usar um objeto dispatcher, chamando executeDispatcher, e passando o objeto, o nome do método e um array de argumentos. Que espécie de sadismo leva alguém a projetar uma solução como essa? Vale lembrar o que diz o Zen do Python:

Se uma implementação é difícil de explicar, é uma idéia ruim.

Outro exemplo interessantíssimo é o protocolo SOAP. Se você precisar construir um serviço SOAP do zero, dê uma investigada na documentação que você vai ter que ler. Compare com a documentação do protocolo XML-RPC, para ter uma idéia.

Meninos, o tio vai ensinar um segredo a vocês, a complexidade se reproduz assexuadamente. Há muito código complexo demais por aí. Se você encontrar indícios de complexidade hoje, corte antes que ela se reproduza, porque ela tende a fugir do controle. Cada vez que você deixa uma implementação complexa num componente de um sistema, você está complicando um pouquinho todos os pontos do sistema que usam aquele. Os resultados ruins são exponenciais. Por mais talentoso que você seja, se deixar a complexidade se enraizar e crescer, vai chegar um momento em que a lógica vai “jogar a toalha” e você vai começar a programar na base da tentativa e erro.

Lembre-se, então, partes simples, conectadas por interfaces simples. Complicado é errado, feio e mau, faz você entregar atrasado e com bugs. E, se precisar de inspiração, abra o Python e digite:

import this

Flash 10 no Linux

Ao contrário do Luis Eduardo Fernando, tenho sido nos últimos anos um feliz usuário de Linux. Funcionava tudo, ou quase. Tenho um LG R405[bb]. Funciona o controle de bateria, de velocidade do cooler, brilho da tela, tenho volumes independentes para o microfone e caixa de som embutidos, e microfone e caixa de som externos. Funciona rede com e sem fio, o modo de hibernação, mouse externo, pen-drive, o modem da Claro[bb], impressora, e tudo mais que precisei.

O Ubuntu é tão simples de configurar e usar na interface gráfica, sem precisar abrir o terminal, que o pessoal aqui faz uma piada chamando-o de “Microsoft Ubuntu”. Mas faltava uma coisa. A versão 9 do Flash Player que a Macromedia disponibiliza tem alguns problemas no Linux. Os dois principais são a falta do window mode transparent, o que faz com que aqueles sites que tem um “layer” Flash sobre o conteúdo fiquem bem estranhos, às vezes impossíveis de usar, e a falta de suporte a v4l2. A v4l2 (Video 4 Linux 2) é a biblioteca que faz funcionar a maioria das webcams. Ou seja, minha webcam funcionava em todos os programas, menos no Flash Player. Isso me impedia de, por exemplo, fazer streammings no UStream.

O problema foi resolvido. Você pode baixar a versão 10 do Flash Player direto do site da Adobe. Com ela temos window mode transparent, e minha webcam está funcionando que é uma beleza.

E, para aqueles que têm medo de terminal, a instalação é extremamente simples. Baixe o “.deb” para Ubuntu, salve no Desktop (ou onde você preferir) e dê um duplo clique. Vai aparecer o instalador de pacotes, com as informações do pacote e um único botâo, “Instalar Pacote”. Clique nele, coloque sua senha de administração, espere a instalação terminar e reinicie o Firefox.

Integrando o Vim com ferramentas externas

Depois que comecei a usar o Vim nas palestras em que eu escrevo código, muita gente começou a me escrever com dúvidas sobre o editorzinho. Apesar de eu dizer nas palestras que Vim é complicado, parece que o pessoal não tem medo. E a dúvida mais freqüente é sobre a integração entre o Vim e ferramentas externas, principalmente o txt2tags.

Faz parte da filosofia Unix que um programa seja facilmente integrado a outros através de interfaces de texto, e o Vim implementa isso muito bem. Para começar, abra o Vim e execute:

:!ls

Você vai ver que o Vim vai executar o comando ls. Então guarde isso, o sinal de exclamação (!) executa comandos externos. Há duas maneiras de fazer o Vim falar com esses comandos. A primeira é mandar o Vim ler a entrada do comando. Digite:

:r!ls

Você vai notar que o Vim vai executar o comando ls e colocar o conteúdo no buffer de edição. A outra maneira de fazer o Vim falar com os programas externos é selecionar texto. Aperte i para ir para o modo de edição e digite:

zebra
tesoura
banana
macaco
felicidade
abacate

Ao terminar de digitar, pressione ESC para voltar ao modo de comando, em seguida SHIFT+V para ir para o modo de seleção de linha e selecione todo o bloco. Com o bloco selecionado, digite:

:!sort

O vim vai colocar, antes do comando, os sinais de seleção ‘<,'>. Não se preocupe, apenas digite o comando e aperte ENTER. Você vai ver que o Vim vai executar o comando sort do sistema operacional, passando como entrada o texto selecionado, e vai substituir esse texto pela saída do comando. Isso, ao final, vai te dar a lista ordenada, assim:

abacate
banana
felicidade
macaco
tesoura
zebra

Usando essa interface simples você pode fazer o Vim falar com qualquer programa Unix.

txt2tags

O programa que eu tenho usado durante as palestras e mais tem deixado as pessoas curiosas é o txt2tags, desenvolvido pelo Aurélio Marinho. O programa está nos repositórios do Debian, então se você usa Debian ou Ubuntu, pode instalá-lo com o comando:

sudo apt-get install txt2tags

O txt2tags lê as primeiras linhas de texto que recebe como títulos do documento. Além disso, precisaremos de várias opções de linha de comando, o que não é conveniente de se digitar. Então vamos criar um shell script para guardar essas opções e fornecer ao txt2tags linhas de cabeçalho de mentirinha. Eu criei um arquivo chamado tags dentro do diretório /usr/local/bin, com permissão de execução (chmod +x) e o seguinte conteúdo:

#!/bin/bash
(echo "
 
 
 
 
 
" && cat ) | txt2tags -t xhtml --infile=- --no-headers

Em seguida, basta abrir o Vim e digitar, por exemplo:

= Aprenda Online =
A [Visie http://visie.com.br/] oferece cursos de Ajax, Javascript e Tableless.

Em seguida selecione essas duas linhas e execute:

:!tags

Pronto, HTML instantâneo.

Não entre em pânico

Você está usando um terminal conectado a um servidor Unix quando as coisas começam a se comportar de maneira estranha. Depois de algum tempo você descobre o problema. Vai até a mesa de um programador novato e descobre que ele, como root, digitou:

# cd
# rm -rf *

O sujeito percebeu a burrada antes de apagar os diretórios /usr e /users. Nesse caso, /users continha os diretórios home. Mas todo o resto do sistema se foi, incluindo /dev, /etc e /bin.

O que você faria? Para complicar as coisas, esta história aconteceu há um bocado de tempo, numa VAX. Ou seja, não era só fazer um boot com um live-CD, fazer um backup dos dados dos usuários e reinstalar o sistema.

O que fazer? Não entrar em pânico. Uma história e tanto.