Alguém conhece algum recurso que fale sobre práticas recomendadas ou padrões de design para scripts de shell (sh, bash etc.)?
design-patterns
bash
shell
user14437
fonte
fonte
Respostas:
Escrevi scripts shell bastante complexos e minha primeira sugestão é "não". O motivo é que é bastante fácil cometer um pequeno erro que atrapalha o seu script ou até mesmo o torna perigoso.
Dito isto, não tenho outros recursos para passar, mas minha experiência pessoal. Aqui está o que eu normalmente faço, que é um exagero, mas tende a ser sólido, embora muito detalhado.
Invocação
faça seu script aceitar opções longas e curtas. tenha cuidado porque existem dois comandos para analisar opções, getopt e getopts. Use getopt ao enfrentar menos problemas.
Outro ponto importante é que um programa sempre deve retornar zero se for concluído com êxito, diferente de zero se algo der errado.
Chamadas de função
Você pode chamar funções no bash, lembre-se de defini-las antes da chamada. As funções são como scripts, elas podem retornar apenas valores numéricos. Isso significa que você precisa inventar uma estratégia diferente para retornar valores de sequência. Minha estratégia é usar uma variável chamada RESULT para armazenar o resultado e retornar 0 se a função for concluída corretamente. Além disso, você pode gerar exceções se estiver retornando um valor diferente de zero e definir duas "variáveis de exceção" (mina: EXCEPTION e EXCEPTION_MSG), a primeira contendo o tipo de exceção e a segunda uma mensagem legível por humanos.
Quando você chama uma função, os parâmetros da função são atribuídos aos vars especiais $ 0, $ 1 etc. Sugiro que você os coloque em nomes mais significativos. declare as variáveis dentro da função como local:
Situações propensas a erros
No bash, a menos que você declare o contrário, uma variável não definida é usada como uma sequência vazia. Isso é muito perigoso no caso de erros de digitação, pois a variável mal digitada não será relatada e será avaliada como vazia. usar
para impedir que isso aconteça. Porém, tenha cuidado, pois se você fizer isso, o programa será interrompido toda vez que você avaliar uma variável indefinida. Por esse motivo, a única maneira de verificar se uma variável não está definida é a seguinte:
Você pode declarar variáveis como somente leitura:
Modularização
Você pode obter a modularização "semelhante a python" se usar o seguinte código:
você pode importar arquivos com a extensão .shinc com a seguinte sintaxe
importar "AModule / ModuleFile"
O qual será pesquisado em SHELL_LIBRARY_PATH. Como você sempre importa no espaço para nome global, lembre-se de prefixar todas as suas funções e variáveis com um prefixo adequado; caso contrário, você corre o risco de conflitos de nome. Eu uso o sublinhado duplo como o ponto python.
Além disso, coloque isso como a primeira coisa no seu módulo
Programação orientada a objetos
No bash, você não pode fazer programação orientada a objetos, a menos que construa um sistema bastante complexo de alocação de objetos (pensei nisso. É viável, mas insano). Na prática, você pode, no entanto, fazer "programação orientada a Singleton": você tem uma instância de cada objeto e apenas uma.
O que faço é: defino um objeto em um módulo (consulte a entrada de modularização). Em seguida, defino vars vazios (análogos às variáveis de membro), uma função init (construtor) e funções de membro, como neste código de exemplo
Capturar e manipular sinais
Achei isso útil para capturar e manipular exceções.
Dicas e sugestões
Se algo não funcionar por algum motivo, tente reordenar o código. A ordem é importante e nem sempre intuitiva.
nem considere trabalhar com o tcsh. não suporta funções e é horrível em geral.
Espero que ajude, embora observe. Se você precisar usar o tipo de coisa que escrevi aqui, significa que seu problema é muito complexo para ser resolvido com o shell. use outro idioma. Eu tive que usá-lo devido a fatores humanos e legado.
fonte
getopt
vsgetopts
?getopts
é mais portátil e funciona em qualquer shell POSIX. Especialmente porque a questão são práticas recomendadas de shell, em vez de práticas recomendadas especificamente para bash, eu daria suporte à conformidade com POSIX para dar suporte a vários shells quando possível.Dê uma olhada no Advanced Bash-Scripting Guide para obter mais informações sobre scripts de shell - e não apenas sobre o Bash.
Não ouça as pessoas dizendo para você procurar outros idiomas, sem dúvida mais complexos. Se o script de shell atender às suas necessidades, use-o. Você quer funcionalidade, não fantasia. Novos idiomas fornecem novas habilidades valiosas para o seu currículo, mas isso não ajuda se você tiver um trabalho que precisa ser feito e já conhece o shell.
Como afirmado, não existem muitas "práticas recomendadas" ou "padrões de design" para scripts de shell. Usos diferentes têm diretrizes e tendências diferentes - como qualquer outra linguagem de programação.
fonte
O shell script é uma linguagem projetada para manipular arquivos e processos. Embora seja ótimo para isso, não é uma linguagem de uso geral; portanto, tente sempre colar a lógica dos utilitários existentes, em vez de recriar a nova lógica no shell script.
Fora esse princípio geral, eu coletei alguns erros comuns de script de shell .
fonte
Houve uma ótima sessão na OSCON deste ano (2008) sobre apenas este tópico: http://assets.en.oreilly.com/1/event/12/Shell%20Scripting%20Craftsmanship%20Presentation%201.pdf
fonte
Saiba quando usá-lo. Para comandos de colagem rápida e suja, tudo bem. Se você precisar tomar mais do que poucas decisões não triviais, loops, qualquer coisa, escolha Python, Perl e modularize .
O maior problema com o shell geralmente é que o resultado final se parece com uma grande bola de lama, 4000 linhas de bash e crescendo ... e você não pode se livrar dele, porque agora todo o seu projeto depende disso. Claro, começou em 40 linhas de festança bonita.
fonte
Fácil: use python em vez de scripts de shell. Você obtém um aumento de quase 100 vezes na legibilidade, sem ter que complicar tudo o que não precisa e preservando a capacidade de evoluir partes do seu script em funções, objetos, objetos persistentes (zodb), objetos distribuídos (pyro) quase sem nenhum código extra.
fonte
use set -e para não avançar após erros. Tente torná-lo compatível, sem depender do bash, se você deseja que ele seja executado no não-linux.
fonte
Para encontrar algumas "melhores práticas", veja como as distribuições Linux (por exemplo, Debian) escrevem seus scripts de inicialização (geralmente encontrados em /etc/init.d)
A maioria deles não possui "bash-isms" e possui uma boa separação de definições de configuração, arquivos de biblioteca e formatação de origem.
Meu estilo pessoal é escrever um shellscript mestre que defina algumas variáveis padrão e tente carregar ("fonte") um arquivo de configuração que possa conter novos valores.
Eu tento evitar funções, pois elas tendem a tornar o script mais complicado. (Perl foi criado para esse fim.)
Para garantir que o script seja portátil, teste não apenas com #! / Bin / sh, mas também use #! / Bin / ash, #! / Bin / dash, etc. Você verá o código específico do Bash em breve.
fonte
Ou a citação mais antiga, semelhante ao que João disse:
"Use perl. Você vai querer conhecer o bash, mas não usá-lo."
Infelizmente eu esqueci quem disse isso.
E sim, hoje em dia eu recomendaria python sobre perl.
fonte