Infra - Linux

Maus hábitos em bash

Frequentemente, fazemos uso incorreto de comandos em bash. Não que faça muita diferença, mas não custa nada aprendermos algumas regrinhas, que tornarão o nosso código mais eficiente e legível.

por Rubens Queiroz de Almeida



Frequentemente, fazemos uso incorreto de comandos em bash. Não que faça muita diferença, mas não custa nada aprendermos algumas regrinhas, que tornarão o nosso código mais eficiente e legível.

Comando cat

Muitos de nós (eu inclusive) temos o hábito de fazer coisas como:

  cat arquivo.txt | wc -l

O comando cat significa catenate, que significa concatenar. Se eu tenho apenas um arquivo, não preciso do cat, posso usar o wc diretamente:

  wc -l arquivo.txt

Já se eu quisesse contar o número de linhas em diversos arquivos, eu poderia usar o cat com o comando wc:

  cat arquivo1.txt arquivo2.txt arquivo3.txt | wc -l

Mas tudo irá depender do que se quer fazer. O comando wc também pode ser usado com esta finalidade, mas a saída é ligeiramente diferente:

  $ wc -l /etc/passwd /etc/hosts
    39 /etc/passwd
    12 /etc/hosts
    51 total

Com o cat:

  $ cat /etc/passwd /etc/hosts | wc -l
  51

O comando wc é mais falante e se eu faço uso deste recurso em uma situação em que preciso apenas do número de linhas, esta verbosidade precisará ser tratada de alguma forma, o que é desnecessário.

Comando ls

Um erro bem comum:

  for arquivo in `ls *`
  do
   ...
  done

Eu não preciso usar o ls para obter uma listagem dos arquivos em um diretório neste trecho. Eu posso fazer assim:

  for arquivo in *
  do
   ...
  done

Uma outra variação desta prática, com o comando cat:

  cat `ls *`

Porque não fazer assim?

  cat *

Cuidado com o rm

Quem nunca fez algo assim?

  rm -rf ~/ *.trash

O que a pessoa queria? Remover de seu diretório pessoal todos os arquivos terminados em trash. O que aconteceu? Este infeliz removeu todo o seu diretório pessoal e apagou os arquivos terminados em trash do diretório corrente. O causador de tudo isto foi o espaço em branco entre ~/ e *.trash. A pressa é inimiga da perfeição :-(

Na verdade o que ele queria era:

  rm -rf ~/*.trash

while ou for?

Vejamos:

  for f in `cat arquivo.txt`
  do
    ...
  done

Podemos fazer também assim:

  while read f
  do
   ...
  done < arquivo.txt

Na primeira opção, o resultado do comando `cat arquivo.txt`, pode ser uma linha mais longa do que o seu sistema pode tratar, o que pode trazer resultados indesejáveis.

Referências

  • Useless Use of Cat Award - grande parte desta dica foi baseada nesta página. Leitura obrigatória, com diversos outros exemplos interessantes.
  • Useless use of cat
  • Shell Script Profissional - O livro Shell Script Profissional, de autoria do Aurélio Marinho Jargas, é referência obrigatória para quem deseja programar como gente grande :-) Vale cada centavo!
Rubens Queiroz de Almeida

Rubens Queiroz de Almeida - Mantenedor do site Dicas-L (http://www.dicas-l.com.br).