Skip to content

Coding Style

Aurelio Jargas edited this page Mar 25, 2015 · 40 revisions

Alinhamento

Sempre deixe o código bem alinhado, espaçado e comentado. Assim você facilita o entendimento do seu código para os leitores. Maçarocas e oneliners não são bem-vindos.

  • Use o Tab para alinhar blocos (indent).
  • Somente um comando por linha.
  • Comente o que faz um trecho de código.
  • Comente linhas mais complicadas de entender.
  • Procure limitar as linhas a 78 colunas no máximo. (opcional)
  • Sempre use espaços ao redor dos operadores, como >, <, && e ||.
  • Lembre-se que você pode quebrar comandos após o pipe sem precisar escapar:
cat /etc/passwd |
    grep '^root' |
    cut -d : -f 4 |
    sed 's/.*/O nome do root: &/'

Na dúvida, basta olhar as funções já existentes e fazer igual. Alguns exemplos:

Variáveis

  • Use somente letras minúsculas no nome das variáveis.
  • Use somente variáveis locais. Sempre use o comando local no início da função, assim você não polui a shell do usuário com variáveis globais.
  • Prefira sempre nomes em português (sem acentos).
  • Variáveis locais com atribuição, use somente uma por linha
local a=1
local b=2
local c=3

Nome da função

  • O nome da função será sempre zz[a-z0-9]+.
  • Não use acentuação, hífen, underscore, pontuação nem letras maiúsculas.
  • Procure escolher um nome descritivo e curto para a função.
  • Se a função for de tradução ou pesquisa em dicionários, seu prefixo deve ser zzdic.
  • Prefira sempre nomes em português (sem acentos).
  • Veja os nomes das funções atuais para se inspirar.

Subshell

  • SEMPRE use $(...) ao invés de `...` para abrir uma subshell, sem exceção.

Blocos de comandos

A legibilidade é mais importante do que a concisão, SEMPRE.

Evite uso dos operadores && e || para simular if/then/else/fi. Esta prática, além de não ser "estilo shell", pode induzir a erros de lógica. Em vez disso:

[ "$bla" ] && {
	cmd1
	cmd2
}

Faça assim:

if [ "$bla" ]
then
	cmd1
	cmd2
fi

E por falar nisso, usar o [ como abreviação para o comando test também não é "estilo shell", isso é açúcar sintático para quem vem de outras linguagens. Acostume-se a usar sempre o comando test e suas opções -n, -z, -gt, etc.

if test -n "$bla"
then
	cmd1
	cmd2
fi

Acostume-se a sempre colocar cada palavra-chave dos comandos if/for/while em uma linha separada:

if foo
then
	cmd1
	cmd2
else
	cmd3
	cmd4
fi


for i in 1 2 3 4 5
do
	cmd1 "$i"
done


while read foo
do
	cmd1 "$foo"
done < arquivo.txt

E claro, não custa repetir: sempre alinhe o conteúdo de cada bloco com um Tab.

Opções de linha de comando

  • Ao criar opções, siga o formato GNU, com opções curtas (-a, -e) e/ou longas (--atualiza).
  • As opções -h e --help já estão reservadas para o texto de ajuda.
  • Prefira sempre nomes em português (sem acentos).

Interatividade zero

Não faça funções interativas. Todas as Funções ZZ devem funcionar sem necessitar de intervenção do usuário durante a execução.

Digitou o comando, obtém a resposta. E é isso.

Resultado via STDOUT, claro, sucinto e organizado

O resultado da função geralmente é um texto, e este texto deve ser de fácil leitura e manipulação. O resultado pode ser usado como entrada para outro comando, ou ainda, pode ser lido por um leitor de telas para deficientes visuais.

Assim sendo, mande sempre para a tela (STDOUT) e não floreie.

Não coloque nenhum tipo de frufru no resultado da função: texto explicativo, adornos visuais, linhas em branco ao redor, espaços no início, nada. Devolva somente a informação que o usuário deseja, iniciando já na primeira linha e primeira coluna do resultado. Menos é mais.

A função precisa retornar uma data? Devolva simplesmente: 31/12/1999. E só, mais nada. É totalmente desnecessário fazer algo como: A data calculada é 31/12/1999.

A função precisa retornar duas datas? Coloque uma em cada linha. Simples assim. Fica fácil para ler e para outro programa obter cada data (no caso, linha) separadamente.

Se a função precisa retornar os dados em colunas, digamos Data, Nome e URL, use o TAB como separador das colunas, sempre que possível. Ele é o separador padrão dos comandos do sistema: cut, paste, sort, ...

Se não há resultados, simplesmente não retorne nada. Nunca mostre na tela mensagens como "resultado não encontrado".

### Não, não, não.

resultado=$($ZZWWWDUMP http://www...)

if test -n "$resultado"
then
	echo $resultado;
else
	echo "Palavra não encontrada"
fi

#---------------------------------------

### Faça simplesmente assim:

$ZZWWWDUMP http://www...

O resultado deve ser composto de linhas inteiras, ou seja sempre deve ter a quebra \n no final da linha. Cuidado com comandos como printf, que por padrão não emitem o \n no final.

# errado
prompt$ zzfoo bar
BARprompt$

# certo
prompt$ zzfoo bar
BAR
prompt$

Bash

Sua função deve ser escrita para o shell Bash. Sem exceções.

Sempre use aspas

No shell, se uma variável não está protegida por "aspas", são tentadas algumas expansões para casar nomes de arquivo. Isso é geralmente não desejado nas funções e pode abrir brechas de segurança. Por exemplo, você faz uma função como a zzcarnaval que espera receber um ano, e o usuário informa *.txt.

Ou ainda, hoje aquela variável recebe apenas uma palavra, então não é preciso colocar aspas nela. Mas e se amanhã você muda a função e ela começa a receber duas ou mais palavras? Vai quebrar se não tiver aspas.

Acostume-se a sempre usar aspas ao redor de todas as variáveis e textos, mesmo que pareça desnecessário. Sua vida fica mais tranquila, e é mais seguro.

  • Na dúvida se precisa de aspas ou não, coloque aspas.
  • Ao redor de variáveis com conteúdo do usuário, coloque aspas: foo="$1", texto="$*"
  • Ao fazer um echo, coloque aspas: echo "Erro número $n"
  • Se não tiver variáveis dentro, use aspas simples: echo 'Erro número 123'

Comando test

Ao testar o conteúdo de uma variável informada pelo usuário, ou de conteúdo desconhecido, inverta a ordem dos argumentos para evitar problemas:

if test "$1" = 'foo'    # errado
if test 'foo' = "$1"    # certo

Isso porque caso a variável em questão contenha algum caractere especial para o test, como ! ou (, dará erro de sintaxe, pois o comando será executado como:

if test ! = 'foo'
if test ( = 'foo'

Não complique — KISS

  • A função deve ser simples.
  • A função deve fazer uma única tarefa.
  • Inspire-se nos comandos do Unix: foco simples e definido.
  • Não tente abraçar o mundo numa única função.

Muito importante ler também: