Peczenyj's Blog

Just Another /Perl|Ruby|C++|Java|Python|JavaScript|Flash|Bash/ Hacker

Resolvendo Problemas Comuns 3 - Missing Separator

O make é um comando incrivelmente poderoso, principalmente para programadores, permitindo que tarefas sejam organizadas de acordo com dependências, por exemplo.

Um caso básico seria construir um grande programa, composto de diversos arquivos-fonte. O Makefile permite que vc compile apenas os arquivos que vc alterou desde o ultimo build, por exemplo, comparando o timestamp do fonte com o codigo objeto gerado.

Bom, ai um Makefile poderoso foi editado num editor de texto profissional e, na hora de testar, nos deparamos com:
$ make    
Makefile:3: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.

$ cat Makefile # nome padrão de arquivo para o make.
# um makefile comum
all:
@echo "oi mundo"


Puxa, parece tudo certo… entretanto ai vai um pequeno detalhe: para cada target do makefile, os comandos que vem a seguir devem começar por um TAB (alias a mensagem de erro é bem clara nesse sentido, certo?). Vamos conferir:

$ cat -A Makefile   # é mais pontente que o -v
# um makefile comum$
all:$
@echo "oi mundo"$


Tcharam! Se a linha do echo iniciasse com um TAB, como deveria ser, apareceria um ^I no inicio da linha. Provavelmente a origem disso é um editor de texto que transforma os TABS em 8 espaços por questões estéticas. Vamos corrigir o Makefile?

$ sed  -i 's/^\ \{8\}/\t/' Makefile
$ cat -A Makefile
# um makefile comum$
all:$
^I@echo "oi mundo"$
$ make
oi mundo


Pronto, basta substituir os espaços por TAB. Outra solução corrigir em um editor de textos mas sem a opção de expansão dos TABs – no vim basta fazer

:set noexpandtab


e editar numa boa.

Resolvendo Problemas Comuns 1 - Permission Denied

Não é incomum, quando não temos experiência em shell, passar por uma situação dessas:

$ ./script.sh
-bash: ./script.sh: Permission denied


Antes de sair olhando se há algo errado com o script, vamos analisar a mensagem de erro em pt_BR: Permissão negada. Diferente de outros sistemas operacionais, no mundo *nix o que faz de um arquivo um programa executável não é a sua extensão e sim as suas permissões.

Resumidamente, existem 3 permissões básicas quando se trata de arquivos: ler, escrever e (finalmente) executar (representado pelas letras r,w e x, respectivamente). Isto é o que impede um usuário de conseguir ler os documentos de outro, por exemplo. Então, um programa, para ser executado, precisa ter esta permissão correspondente, e ai entra o comando chmod.

$ ls -l script.sh
-rw-r--r-- 1 peczenyj users 22 2007-07-26 11:08 script.sh
$ chmod +x script.sh # vamos ativar o bit de execução (x)
$ ls -l script.sh
-rwxr-xr-x 1 peczenyj users 22 2007-07-26 11:08 ./script.sh
$ ./script.sh #agora sim!!!
oi


Problema resolvido.

Resolvendo Problemas Comuns 2 - Bad Interpreter

Seguindo na nossa sessão de dicas, quem nunca passou por isso?

$ ./script.sh
: bad interpreter: No such file or directory

$ cat script.sh
#!/bin/bash
echo "oi"

- Hein? Mas está tudo certo, eu tenho um /bin/bash, o que está acontecendo?

Bom, vamos ver mais de perto:
$ cat -v script.sh  # 'show nonprinting'
#!/bin/bash^M
echo "oi"^M


Ahá! Tem um ^M no final das linhas atrapalhando.
- Mas o que é isso?
Muito provavelmente a origem desde script é uma maquina windows. A explicação é o caracter newline. O windows precisa de 2 caracteres para simbolizar o fim de uma linha em um arquivo texto puro, a dupla \r\n (veja link para a wikipedia), porém os *nix não precisam do \r – que o cat gentilmente mostrou como um ^M. Este caracter a mais atrapalha o interpretador, que não recebe um /bin/bash e sim /bin/bash\r – e isso realmente não existe.

Como resolver? Existem dois programas para este fim: unix2dos e dos2unix (as vezes aparecem como unixtodos e dostounix) que convertem os finais de linha em casos como este. Se vc abrir um arquivo texto do *nix em um bloco de texto vai ver todas as quebras de linha substituidas por um quadrado preto e todas as linhas em uma só.

Caso vc não tenha um programa conversor, pode usar o SED
$ sed -i 's/\r$//' script.sh
$ ./script.sh
oi


O tr também poderia ser usado, mas não é tão amigável.
$ tr -d '\r' < script.sh > novo_script.sh


Este detalhe pode ser muito importante um dia!

Comments

arpapa
Pode também converter usando o comando dos2unix script.sh que funciona legal.
Rioges
Resolveu o meu problema, muito obrigado pela dica!!

Tio Maneco

Quem se lembra do Tio Maneco?

Pois bem, descobri que foi aprovada a captação de recursos para a produção do filme “As aventuras de Reina Caiman em o resgate do Maneco” (RF Cinema e TV Ltda).

Pra mim, este é o filme mais esperado de todos os tempos, mal posso esperar para ver o Flávio Migliaccio de novo, em um dos papeis mais legais e inteligentes da tv brasileira – afinal os filmes são impossiveis de serem achados e a série original foi apagada acidentalmente pela tv cultura.

(se alguem tiver mais informações, please, me avise!!!)

Comments

Tiago Peczenyj
Sim, o Flávio tava processando a Cultura até. Não sei a quantas anda isso, o que é uma pena pois eu tinha boas lembranças da série.

Nem lembro do nome dos Robos feitos com bules e chaleiras :(
panglossa
É verdade que foi tudo perdido? “Apagado acidentalmente”?