Configuração do usuário de um script de shell. Melhores Práticas?


13

Estou escrevendo um script de shell com algumas variáveis ​​que devem ser configuradas pelo usuário. Haverá um instalador para baixar e configurar o script, possivelmente fazendo uma série de perguntas. O script em questão é destinado a outros desenvolvedores.

Isso pode ser implementado de várias maneiras:

  1. Use espaços reservados no próprio script e sedsubstitua-os durante a instalação (algo como isto: /programming/415677/how-to-replace-placeholders-in-a-text-file )

    • Prós: todas as definições de variáveis ​​estão contidas no script. É fácil fazer o download do script manualmente e configurar as variáveis ​​para usuários que preferem um editor ao instalador.

    • Contras: É difícil reconfigurar as variáveis ​​através do instalador, uma vez que elas estão no lugar. A menos que eu crie uma regexp mais complexa, propensa a erros.

  2. Use um arquivo de configuração , basicamente outro script de shell com atribuições e use-o sourcepara incluí-lo. (E provavelmente coloque-o ~/.scriptname? O script principal é copiado para /usr/local/bin)

    • Prós: É fácil reconfigurar o script. Poderia até adicionar um parâmetro para fazê-lo no script principal (provavelmente funcionaria também na primeira solução, mas editar um script por si só não parece uma boa ideia)

    • Contras: Agora, o script depende de dois arquivos e é necessário que o usuário execute o instalador para que o arquivo de configuração seja criado. Isso pode ser resolvido gerando automaticamente um arquivo de configuração, se não houver nenhum. Mas localizar um arquivo de configuração externo ainda será mais complicado para os usuários que desejam apenas baixar o script, editá-lo e concluir o processo.

Além disso, algumas opções sobre como a configuração deve ser gerenciada pelo usuário após a instalação:

  1. Git como
    $ myscript config server.host example.org $ myscript config server.proxypath / home / johndoe / proxy $ myscript config server.httppath / home / johndoe / web


  2. Configuração interativa do $ myscript
    Digite o nome do host do servidor: exemplo.org
    Digite o caminho para o proxy no servidor: / home / johndoe / proxy
    Digite o caminho para o diretório http no servidor: / home / johndoe / web

  3. getopts com opções longas
    $ myscript --host example.org --proxypath / home / johndoe / proxy --httppath / home / johndoe / web


  4. Exemplo simples de configuração do $ myscript.org / home / johndoe / proxy / home / johndoe / web

Existem outras maneiras de fazer isso que você consideraria?
Alguma prática recomendada, algo elegante?


2
Não duvido que você possa escrever um script de shell que faça tudo isso, mas a questão é por que você deseja escrever algo tão complexo, pois requer um instalador em um script de shell. De qualquer forma, veja como o sistema de configuração do kernel Linux gerencia seu arquivo de configuração.

Bem. O script 'installer' baixaria apenas o script real, copiava-o para o local correto e fazia uma série de perguntas para a configuração (3-4 variáveis). Dessa forma, posso fornecer aos usuários uma única linha de comando, executando o script de instalação e direcionando-o para / bin / sh. É claro que eu poderia pular o instalador e apenas adicionar um parâmetro 'install' ao script principal. Talvez uma solução melhor, o que você acha?
Charlie Rudenstål

"mas a questão é por que você deseja escrever algo tão complexo", aqui está o script em questão: github.com/charlie-rudenstal/depo Estou tentando reduzir a quantidade de etapas que os novos usuários precisam executar, especialmente durante o instalação. Também está pensando em tornar a configuração necessária do servidor automática.
Charlie Rudenstål

Respostas:


6

O que eu esperaria de um programa são (um script de shell ou não):

  • Eu nunca tenho que alterar o executável para apenas configurá-lo. Este não é um kernel do SO.
  • Eu posso passar qualquer configuração usando a linha de comando. Esta é uma obrigação para todas as informações que não possuem um padrão razoável. A única exceção é uma senha que precisa de entrada interativa.
  • Opcionalmente, posso passar uma configuração usando uma variável de ambiente.
  • Posso escrever as configurações em um arquivo de configuração, e esse arquivo será usado se estiver presente com um nome conhecido ou explicitamente apontado para o uso dos dois métodos acima.
  • O arquivo de configuração usa os mesmos nomes e sintaxe de configuração da linha de comando.

Ótimo conselho. Essa seria sua ordem preferida? (1) Verifique as configurações aprovadas na linha de comando (2) Verifique as configurações em um .scriptnameConfig no mesmo diretório (3) Verifique as configurações em uma variável de ambiente (4) Verifique as configurações em um .scriptnameConfig em ~ / .scriptnameConfig (5) Use o padrão definição
Charlie Rudenstål

"O arquivo de configuração usa os mesmos nomes e sintaxe de configuração da linha de comando." - Como isso deve parecer? Eu usaria a sintaxe de atribuição para scripts de shell regulares: SETTING = VALUE. Comando como sintaxe não seria um pouco estranho dentro de um arquivo de configuração?
Charlie Rudenstål

Veja como mountou sshpermita que você use a mesma sintaxe na linha de comando e na configuração. Você não precisa copiar totalmente a sintaxe da linha de comando; em vez de '--foo = bar', você pode usar 'foo = bar'. Se você usasse 'BarOption: Foo', seria muito menos conveniente: a necessidade de lembrar se o caso é significativo, qual palavra-chave é aceita no arquivo e qual na linha de comando e a incapacidade de copiar e colar um comando em funcionamento alinhar em um arquivo de configuração com apenas edição cosmética.
9000

3

Quando eu preciso escrever um roteiro elaborado com várias opções de configuração que eu uso Python com o argparse e ConfigParser bibliotecas. Isso ajuda na implementação, mas o processo se aplica a qualquer script de shell:

  1. Procure um arquivo de configuração. Se houver, leia todas as configurações existentes em uma tabela de dicionário / pesquisa.
  2. Analise argumentos de linha de comando nomeados. Para cada argumento fornecido, substitua o valor carregado do arquivo de configuração, se existir. Para qualquer argumento não passado na linha de comando e não na configuração, use um padrão.
  3. Executar a função principal do script
  4. Se o arquivo de configuração não existir, escreva os valores passados ​​e / ou padrão nele.

Minha preferência é que um arquivo de configuração mantenha as opções preferidas quando o script for usado repetidamente, mas deixe que quaisquer argumentos da linha de comando sejam substituídos. Escreva o arquivo de configuração usando esses parâmetros na primeira vez em que é executado. O arquivo de configuração pode ser compartilhado e confirmado em um repositório de códigos.

No meu caso mais recente, também escrevi os padrões para a [DEFAULT]seção na parte superior do arquivo de configuração e, em seguida, tive uma seção para cada "ambiente" com substituições apropriadas para cada um. O "ambiente" é o primeiro parâmetro sem nome para o script. Portanto, neste caso parâmetros são escolhidos como built-in padrão -> padrão arquivo de configuração -> valor seção de arquivo de configuração -> parâmetro de linha de comando . Um parâmetro de linha de comando adicional oferece a opção de substituir a configuração existente pelo valor da última execução. Este arquivo de configuração é gravado no diretório atual para ser aplicado por projeto e pode ser confirmado com o restante do código. Qualquer outra pessoa que esteja verificando o mesmo projeto começará com a mesma configuração.


"Um parâmetro de linha de comando adicional oferece a opção de substituir a configuração existente pelo valor da última execução." Essa é uma abordagem interessante. Uma maneira prática de combinar parâmetros com a configuração.
Charlie Rudenstål

+1, eu também recomendaria definir padrões em um default.configarquivo localizado no mesmo diretório que o script, procurando um arquivo de configuração ~/.scriptnamepara substituir esses valores. Dessa forma, todo valor tem um valor padrão válido e é mais fácil de manter.
Aaron

2

A edição de espaços reservados é suscetível a erros.

Eu iria usar um arquivo de configuração.

Sua preocupação com a dependência é válida, no entanto, não me lembro de usar muitas ferramentas compostas por um único arquivo. Então, teoricamente, você está correto, mas na prática deve ficar bem.

Uma terceira opção é fazer com que o software de configuração escreva uma nova versão personalizada, específica das opções e parâmetros selecionados. Pode ser mais difícil escrever e testar, é claro :)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.