Capitalização correta de variáveis ​​de script Bash e shell

191

Eu corro por muitos scripts de shell com variáveis ​​em todas as maiúsculas e sempre achei que há um sério mal-entendido nisso. Meu entendimento é que, por convenção (e talvez por necessidade há muito tempo), as variáveis ​​de ambiente estão em maiúsculas.

Mas em ambientes modernos de script como o Bash, sempre preferi a convenção de nomes em minúsculas para variáveis ​​temporárias e maiúsculas apenas para variáveis ​​exportadas (ou seja, ambiente) . Por exemplo:

#!/usr/bin/env bash
year=`date +%Y`
echo "It is $year."
export JAVA_HOME="$HOME/java"

Essa sempre foi minha opinião sobre as coisas. Existem fontes autorizadas que concordam ou discordam dessa abordagem ou é apenas uma questão de estilo?

JasonSmith
fonte

Respostas:

262

Por convenção, variáveis de ambiente ( PAGER, EDITOR...) e variáveis do shell internos ( SHELL, BASH_VERSION...) são capitalizados. Todos os outros nomes de variáveis ​​devem estar em minúsculas.

Lembre-se de que nomes de variáveis ​​diferenciam maiúsculas de minúsculas; esta convenção evita a substituição acidental de variáveis ​​ambientais e internas.

Mantendo esta convenção, você pode ter certeza de que não precisa conhecer todas as variáveis ​​de ambiente usadas pelas ferramentas ou shells do UNIX para evitar substituí-las. Se for sua variável, minúscula. Se você exportá-lo, coloque-o em maiúsculas.

lhunath
fonte
8
+1. Bom argumento sobre substituição acidental. Esqueci de mencionar, mas agora que você mencionou, acho que decidi usar letras minúsculas porque li ou ouvi falar sobre esse problema.
23909 JasonSmith
5
Eu pensei que o principal motivo para usar nomes de variáveis ​​em maiúsculas era evitar conflitos com os comandos do shell. Recentemente, tivemos o nome do host de um de nossos servidores acidentalmente alterado para '=' porque um script usou uma variável 'hostname'.
precisa saber é o seguinte
25
@ThisSuitIsBlackNot Ignorando o código de baixa qualidade, as variáveis ​​são prefixadas com um dólar quando expandidas e usadas em um local onde não podem ser confundidas com um nome de comando quando não estão. Obviamente, fazer hostname = moo vai causar problemas. Não porque você esteja usando um "nome de host" em minúsculas, mas porque não esteja usando a sintaxe de atribuição correta. A atribuição é feita com hostname = moo, sem espaços. Assumindo o código correto, você não precisa se preocupar com nomes de variáveis ​​em conflito com nomes de comandos.
Lhunath 21/10
3
Todos os livros de texto que olhei sempre em maiúsculas para todas as variáveis ​​do shell. Embora nomes de variáveis ​​em minúsculas sejam permitidos, maiúscula é a convenção.
Brian S. Wilson
3
Eu não sabia disso, e só perdi algumas horas. usando USER="username"em um script bash automatizando alguns comandos remotos sobre ssh em vez de user="username". Ugh! Ainda bem que sei agora!
Gabriel Staples
28

Quaisquer convenções de nomenclatura seguidas consistentemente sempre ajudarão. Aqui estão algumas dicas úteis para nomear variáveis ​​de shell:

  • Use todos os limites e sublinhados para variáveis ​​e constantes exportadas, especialmente quando elas são compartilhadas entre vários scripts ou processos. Use um prefixo comum sempre que aplicável, para que as variáveis ​​relacionadas se destaquem e não colidam com as variáveis ​​internas do Bash, todas em maiúsculas.

    Exemplos:

    • Variáveis ​​exportadas com um prefixo comum: JOB_HOME JOB_LOG JOB_TEMP JOB_RUN_CONTROL
    • Constantes: LOG_DEBUG LOG_INFO LOG_ERROR STATUS_OK STATUS_ERROR STATUS_WARNING
  • Use "snake case" ( todas minúsculas e sublinhados ) para todas as variáveis ​​com escopo definido para um único script ou bloco.

    Exemplos: input_file first_value max_amount num_errors

    Use maiúsculas e minúsculas quando a variável local tiver algum relacionamento com uma variável de ambiente, como: old_IFS old_HOME

  • Use um sublinhado à esquerda para variáveis ​​e funções "particulares". Isso é especialmente relevante se você escrever uma biblioteca de shell em que funções dentro de um arquivo de biblioteca ou entre arquivos precisem compartilhar variáveis, sem colidir com nada que possa ter o mesmo nome no código principal.

    Exemplos: _debug _debug_level _current_log_file

  • Evite estojo de camelo . Isso minimizará os erros causados ​​por erros de digitação de casos. Lembre-se de variáveis ​​de shell diferenciam maiúsculas de minúsculas .

    Exemplos: inputArray thisLooksBAD, numRecordsProcessed,veryInconsistent_style


Veja também:

codeforester
fonte
1
Esta é uma convenção, mas dificilmente é universalmente aceita. A lógica contra o caso dos camelos não é inteiramente convincente. A recomendação de usar SHOUTING para variáveis ​​exportadas é levemente controversa.
Tripleee
3
Não afirmei que é uma convenção comumente seguida. Vi que a maioria dos programadores não pensa seriamente em seguir convenções fortes em scripts de shell e pensou em anotar meus pensamentos com base no que tenho feito.
codeforester
8

Se as variáveis ​​de shell forem exportadas para o ambiente, vale a pena considerar que a Definição de variável de ambiente POSIX (edição 7, 2018) especifica:

Os nomes de variáveis ​​de ambiente usados ​​pelos utilitários no volume Shell e Utilitários do POSIX.1-2017 consistem apenas em letras maiúsculas, dígitos e o sublinhado ( _) dos caracteres definidos no Portable Character Set e não começam com um dígito.

...

O espaço para nome dos nomes de variáveis ​​de ambiente que contêm letras minúsculas é reservado para aplicativos. Os aplicativos podem definir qualquer variável de ambiente com nomes desse espaço de nome sem modificar o comportamento dos utilitários padrão.

Anthony Geoghegan
fonte
6

Eu faço o que você faz. Duvido que exista uma fonte autorizada, mas parece um padrão de fato bastante difundido.

Draemon
fonte
1
Concordo. É porque ALL_CAPS é feio, mas é bom fazer VARIÁVEIS AMBIENTAIS se destacar por ser feio.
03:
1
Concordo com você no estilo de codificação, mas definitivamente não concordo que seja generalizado! Scripts shell é uma daquelas línguas colaterais que as pessoas só aprendem informalmente, e então eu sinto que todo mundo está sempre dizendo LOCALIZAÇÃO =cat /tmp/location.txt
JasonSmith
@ jhs - obviamente tive sorte nos scripts de shell com os quais tive que trabalhar!
23909 Draemon
4
"O espaço de nomes dos nomes de variáveis ​​de ambiente que contêm letras minúsculas é reservado para aplicativos." - POSIX IEEE Std 1003.1-2008 seção 8.1
triplicado
5

Na verdade, o termo "variáveis ​​de ambiente" parece ser de cunhagem bastante recente. Kernighan e Pike em seu livro clássico "The UNIX Programming Environment", publicado em 1984, falam apenas de "variáveis ​​de shell" - não há sequer uma entrada para "ambiente" no índice!


fonte
8
Eu acho que é uma omissão do livro. getenv (), setenv () e environ foram introduzidos na versão 7 do UNIX (1979). pt.wikipedia.org/wiki/Version_7_Unix
Juliano
3
Esse livro observa que as variáveis ​​maiúsculas têm um significado especial.
Ashawley 23/03/09
3

É apenas uma convenção amplamente aceita, duvido que exista alguma fonte "autorizada" para isso.

Alnitak
fonte
1

Eu costumo usar ALL_CAPS para variáveis ​​globais e de ambiente. é claro, no Bash não há escopo de variável real, portanto, há uma boa parte das variáveis ​​usadas como globais (principalmente configurações e rastreamento de estado) e relativamente poucos 'locais' (contadores, iteradores, seqüências parcialmente construídas e temporários)

Javier
fonte
Sim, eu conceitualmente penso em variáveis ​​não exportadas como locais, já que o Bash costuma forçar os processos filho a fazer o que for necessário.
23909 JasonSmith