É comum dividir um script maior em vários scripts e fornecê-los no script principal?

21

No momento, estou desenvolvendo um script Bash maior (é um projeto de código aberto meu) e está começando a se tornar uma bagunça. Eu divido a lógica em funções, uso variáveis locais onde eu posso e só declarei algumas variáveis globais. Ainda assim, está se tornando muito difícil de manter.

Pensei em dividir o script em vários scripts e fornecê-los no meu script principal (semelhante a importações em outros idiomas).

Mas eu me pergunto se essa é uma abordagem viável. Primeiro, a terceirização de vários scripts pode diminuir consideravelmente o tempo de execução do script e, segundo, dificulta a distribuição.

Então, essa é uma boa abordagem e outros projetos (de código aberto) fazem isso da mesma maneira?

    
por helpermethod 07.05.2013 / 17:16

6 respostas

12

Sim, é uma prática comum. Por exemplo, nos primeiros dias do Unix, o código shell responsável por orientar o sistema através de suas fases de inicialização para a operação multiusuário era um único arquivo, /etc/rc . Hoje, o processo de inicialização é controlado por muitos scripts de shell, divididos por função, com funções e variáveis comuns fornecidas conforme necessário a partir de locais centrais. Distribuições Linux, Macs, BSDs, todos adotaram essa abordagem em graus variados.

    
por 07.05.2013 / 17:34
15

O shell é a ferramenta certa para o trabalho nesse ponto? Como um desenvolvedor que esbarrou em problemas de outgrowing code, posso dizer que uma reescrita não deve ser considerada, mas considerar separar as partes em algo mais adequado para a escala que você está procurando para crescer seu aplicativo - talvez python ou ruby ou até perl ?

O shell é uma linguagem de utilitários - é uma linguagem de script - e, portanto, será difícil transformá-lo nesses tamanhos.

    
por 07.05.2013 / 22:07
6

Se facilitar a sua manutenção, você pode ter os dois. Divida-o em partes lógicas para que você possa mantê-lo facilmente e, em seguida, escreva (por exemplo) um Makefile para reuni-lo novamente para distribuição. Você pode escrever alguns scripts rápidos para copiar as funções do arquivo de inclusão para o arquivo de saída no lugar de a linha source ou apenas faça algo trivial como este (você terá que re-tabify isso, pois make requer abas):

all: myscript

myscript: includes/* body/*
    cat $^ > "$@" || (rm -f "$@"; exit 1)

Você então tem uma versão "fonte" (usada para edição) e uma versão "binária" (usada para instalação trivial).

    
por 07.05.2013 / 18:50
4

Um script pode ser quebrado conforme você descreve - praticamente tudo pode ser feito. Eu diria que a 'boa abordagem' seria compartimentar seu roteiro grande, descobrir onde partes dele poderiam ser executadas como um processo separado, comunicando-se através de mecanismos de IPC.

Além disso, para um script de shell, eu o empacotaria como um único arquivo. Como você diz, isso torna a distribuição mais difícil: você precisa saber onde os scripts de 'biblioteca' estão localizados - não há um bom padrão para scripts de shell - ou confiar no usuário para definir seu caminho corretamente.

Você pode distribuir um programa de instalação que lide com tudo isso para você, extraindo os arquivos, colocando-os no local apropriado, dizendo ao usuário para adicionar algo como export PROGRAMDIR=$HOME/lib/PROGRAM ao arquivo ~ / .bashrc. Em seguida, o programa principal poderá falhar se $PROGRAMDIR não estiver definido ou não contiver os arquivos esperados.

Eu não me preocuparia tanto com a sobrecarga de carregar os outros scripts. A sobrecarga é realmente apenas abrir um arquivo; o processamento do texto é o mesmo, especialmente se forem definições de funções.

    
por 07.05.2013 / 17:34
1
Prática comum ou não, eu não acho que terceirizar qualquer coisa que não seja um conjunto de exportações é uma boa ideia. Eu acho que executar o código por meio de sourcing é apenas confuso e limita a reutilização, porque as configurações ambientais e de outras variáveis tornam o código de origem altamente dependente do código de origem.

É melhor dividir seu aplicativo em scripts menores e independentes e executá-los como uma série de comandos. Isso facilitará a depuração, já que você pode executar cada script independente em um shell interativo, examinando arquivos, logs, etc entre cada chamada de comando. Seu script de aplicativo único e grande se transforma em um script de controle mais simples que apenas executa uma série de comandos após a conclusão da depuração.

Um grupo de scripts menores e independentes é executado no problema mais difícil de instalar.

    
por 07.05.2013 / 17:55
1

Uma alternativa ao fornecimento de scripts é simplesmente chamá-los de argumentos. Se você já dividiu a maior parte da sua funcionalidade em funções do shell, provavelmente já está perto de poder fazer isso. O trecho a seguir do Bash permite que qualquer função declarada em um script seja usada como um subcomando:

if [[ ${1:-} ]] && declare -F | cut -d' ' -f3 | fgrep -qx -- "${1:-}"
then "$@"
else main "$@" # Try the main function if args don't match a declaration.
fi

A razão para não source é evitar a poluição ambiental e de opções.

    
por 20.05.2013 / 16:03

Tags