Eu preciso criar um arquivo de configuração para o meu próprio script: aqui está um exemplo:
roteiro:
#!/bin/bash
source /home/myuser/test/config
echo "Name=$nam" >&2
echo "Surname=$sur" >&2
Conteúdo de /home/myuser/test/config
:
nam="Mark"
sur="Brown"
isso funciona!
Minha pergunta: essa é a maneira correta de fazer isso ou existem outras maneiras?
bash
shell
shell-script
Pol Hallen
fonte
fonte
abcde
também faz desta maneira e esse é um programa bastante grande (para um script de shell). Você pode dar uma olhada aqui .Respostas:
source
não é seguro, pois executará código arbitrário. Isso pode não ser uma preocupação para você, mas se as permissões do arquivo estiverem incorretas, pode ser possível que um invasor com acesso ao sistema de arquivos execute o código como um usuário privilegiado injetando código em um arquivo de configuração carregado por um script protegido de outra forma, como um script de inicialização.Até agora, a melhor solução que consegui identificar é a desajeitada solução de reinventar a roda:
myscript.conf
Usando
source
, isso seria executadoecho rm -rf /
duas vezes, além de alterar o usuário em execução$PROMPT_COMMAND
. Em vez disso, faça o seguinte:myscript.sh (Bash 4)
myscript.sh (compatível com Mac / Bash 3)
Por favor, responda se você encontrar uma falha de segurança no meu código.
fonte
*
entradas corretamente, mas o que no Bash trata bem esse caractere?my\\password
Aqui está uma versão limpa e portátil, compatível com o Bash 3 e superior, no Mac e no Linux.
Ele especifica todos os padrões em um arquivo separado, para evitar a necessidade de uma enorme, confusa e duplicada função de configuração de "padrões" em todos os seus scripts de shell. E permite escolher entre ler com ou sem fallbacks padrão:
config.cfg :
config.cfg.defaults :
config.shlib (esta é uma biblioteca, portanto não há linha de shebang):
test.sh (ou qualquer script em que você queira ler os valores de configuração) :
Explicação do script de teste:
printf
linha? Bem, é algo que você deve estar ciente:echo
é um mau comando para imprimir texto sobre o qual você não tem controle. Mesmo se você usar aspas duplas, ele interpretará sinalizadores. Tente definirmyvar
(inconfig.cfg
) para-e
e você verá uma linha vazia, porqueecho
pensará que é uma bandeira. Masprintf
não tem esse problema. Oprintf --
diz "imprima isso e não interprete nada como sinalizadores" e o"%s\n"
diz "formate a saída como uma string com uma nova linha à direita e, por último, o parâmetro final é o valor para o formato printf.myvar="$(config_get myvar)";
. Se você quiser imprimi-los na tela, sugiro usar printf para ser totalmente seguro contra quaisquer seqüências incompatíveis com eco que possam estar na configuração do usuário. Mas eco é bom se a variável fornecida pelo usuário não for o primeiro caractere da string em que você está ecoando, já que essa é a única situação em que "sinalizadores" podem ser interpretados, portanto, algo comoecho "foo: $(config_get myvar)";
é seguro, pois o "foo" não comece com um traço e, portanto, diz ao eco que o restante da string também não é sinalizador. :-)fonte
config.cfg.defaults
de defini-los no momento da ligação$(config_get var_name "default_value")
. tritarget.org/static/…Analise o arquivo de configuração, não o execute.
Atualmente, estou escrevendo um aplicativo no trabalho que usa uma configuração XML extremamente simples:
No script shell (o "aplicativo"), é isso que faço para obter o nome de usuário (mais ou menos, coloquei-o em uma função shell):
O
xml
comando é XMLStarlet , disponível para a maioria dos Unices.Estou usando XML, já que outras partes do aplicativo também lidam com dados codificados em arquivos XML, por isso foi mais fácil.
Se você preferir JSON, existe
jq
um analisador de shell JSON fácil de usar.Meu arquivo de configuração seria parecido com isto em JSON:
E então eu estaria recebendo o nome de usuário no script:
fonte
eval
para definir vários valores, estará executando partes selecionadas do arquivo de configuração :-).eval
nada. O impacto no desempenho do uso de um formato padrão com um analisador existente (embora seja um utilitário externo) é insignificante em comparação com a robustez, a quantidade de código, a facilidade de uso e a manutenção.A maneira mais comum, eficiente e correta é usar
source
ou.
como forma abreviada. Por exemplo:ou
Algo a considerar, no entanto, são os problemas de segurança que o uso de um arquivo de configuração adicional de origem externa pode gerar, dado que um código adicional pode ser inserido. Para obter mais informações, inclusive sobre como detectar e resolver esse problema, eu recomendo dar uma olhada na seção 'Secure it' em http://wiki.bash-hackers.org/howto/conffile#secure_it
fonte
Eu uso isso em meus scripts:
Deve suportar todas as combinações de caracteres, exceto que as chaves não podem ter
=
nelas, pois esse é o separador. Qualquer outra coisa funciona.Além disso, isso é completamente seguro, pois não usa nenhum tipo de
source
/eval
fonte
Para o meu cenário,
source
ou.
estava bom, mas eu queria dar suporte a variáveis de ambiente local (ou seja,FOO=bar myscript.sh
) tendo precedência sobre variáveis configuradas. Eu também queria que o arquivo de configuração fosse editável pelo usuário e confortável para alguém acostumado a obter arquivos de configuração, e mantê-lo o mais pequeno / simples possível, para não distrair o principal impulso do meu pequeno script.Isto é o que eu vim com:
Essencialmente - ele verifica definições de variáveis (sem ser muito flexível sobre espaços em branco) e reescreve essas linhas para que o valor seja convertido em um padrão para essa variável e a variável não seja modificada se encontrada, como a
XDG_CONFIG_HOME
variável acima. Ele origina esta versão alterada do arquivo de configuração e continua.Trabalhos futuros podem tornar o
sed
script mais robusto, filtrar linhas que parecem estranhas ou não são definições, etc., sem interromper os comentários no final da linha - mas isso é bom o suficiente para mim por enquanto.fonte
Isso é sucinto e seguro:
Os
-i
garante que você só obter as variáveis decommon.vars
fonte
Você consegue:
fonte