No meu script em bash, há muitas variáveis e tenho que fazer algo para salvá-las em arquivo. Minha pergunta é como listar todas as variáveis declaradas em meu script e obter uma lista como esta:
VARIABLE1=abc
VARIABLE2=def
VARIABLE3=ghi
set
irá exibir as variáveis, infelizmente também irá exibir as funções definidas também.
Felizmente, o modo POSIX exibe apenas as variáveis:
( set -o posix ; set ) | less
Canalizando less
ou redirecionando para onde você deseja as opções.
Portanto, para obter as variáveis declaradas apenas no script:
( set -o posix ; set ) >/tmp/variables.before
source script
( set -o posix ; set ) >/tmp/variables.after
diff /tmp/variables.before /tmp/variables.after
rm /tmp/variables.before /tmp/variables.after
(Ou pelo menos algo baseado nisso :-))
-o posix
agora, um diff conterá apenas as variáveis.VARS="`set -o posix ; set`"; source script; SCRIPT_VARS="`grep -vFe "$VARS" <<<"$(set -o posix ; set)" | grep -v ^VARS=`"; unset VARS;
. Isso também produzirá os vars em um formato pronto para salvar. A lista incluirá as variáveis que o script alterou (depende se isso é desejável)source
, deve ser capaz de fazê-lo com a saída dedeclare -p
.before=$(set -o posix; set); dosomestuff; diff <(echo "$before") <(set -o posix; set)
Ele lista todas as variáveis, incluindo as locais. Aprendi isso em Get list of variables cujo nome corresponde a um determinado padrão e usei-o em meu script .
fonte
compgen -v
lista também variáveis globais que não foram definidas localmente. Não tenho certeza se esse é um bug antigo ou o comportamento desejado.Isso deve imprimir todos os nomes de variáveis do shell. Você pode obter uma lista antes e depois de fornecer seu arquivo como em "set" para diff quais variáveis são novas (como explicado nas outras respostas). Mas tenha em mente que essa filtragem com diff pode filtrar algumas variáveis que você precisa, mas que estavam presentes antes de fornecer seu arquivo.
No seu caso, se você sabe que os nomes das variáveis começam com "VARIÁVEL", você pode originar seu script e fazer:
ATUALIZAÇÃO: Para solução BASH pura (sem comandos externos usados):
fonte
eval "printf '%q\n' $(printf ' "${!%s@}"' _ {a..z} {A..Z})"
Com base em algumas das respostas acima, isso funcionou para mim:
arquivo fonte :
fonte
Se você pode pós-processar, (como já mencionado) você pode apenas fazer uma
set
chamada no início e no final do seu script (cada um para um arquivo diferente) e fazer uma comparação entre os dois arquivos. Perceba que isso ainda conterá algum ruído.Você também pode fazer isso programaticamente. Para limitar a saída apenas ao seu escopo atual, você teria que implementar um wrapper para a criação de variáveis. Por exemplo
Que rende
fonte
Aqui está algo semelhante à resposta de @GinkgoFr, mas sem os problemas identificados por @Tino ou @DejayClayton, e é mais robusto do que a parte inteligente de @ DouglasLeeder
set -o posix
:A diferença é que esta solução PARA após o primeiro relatório não variável, por exemplo, a primeira função relatada por
set
BTW: O problema "Tino" está resolvido. Mesmo que POSIX esteja desligado e as funções sejam relatadas por
set
, ased ...
parte da solução permite apenas relatórios de variáveis (por exemplo,VAR=VALUE
linhas). Em particular, oA2
que não spuriously fazê-lo na saída.AND: O problema "DejayClayton" foi resolvido (novas linhas incorporadas em valores de variáveis não interrompem a saída - cada
VAR=VALUE
uma obtém uma única linha de saída):NOTA: A solução fornecida por @DouglasLeeder sofre do problema "DejayClayton" (valores com novas linhas embutidas). Abaixo de
A1
está errado eA2
não deve ser exibido.FINALMENTE: Eu não acho que a versão de
bash
importe, mas pode. Eu fiz meu teste / desenvolvimento neste:PÓS-SCRIPT: dadas algumas das outras respostas ao OP, tenho <100% de certeza de que
set
sempre converte novas linhas dentro do valor para\n
, no qual essa solução depende para evitar o problema "DejayClayton". Talvez seja um comportamento moderno? Ou uma variação em tempo de compilação? Ou uma configuração de opçãoset -o
oushopt
? Se você souber de tais variações, por favor, adicione um comentário ...fonte
Tente usar um script (vamos chamá-lo de "ls_vars"):
chmod + x it, e:
fonte
A partir de uma perspectiva de segurança, quer de @ akostadinov resposta ou de @ JuvenXu resposta é preferível confiando na saída desestruturado do
set
comando, devido ao seguinte potencial falha de segurança:A função acima
doLogic
usaset
para verificar a presença de variávelPS1
para determinar se o script é interativo ou não (não importa se esta é a melhor maneira de atingir esse objetivo; este é apenas um exemplo).No entanto, a saída de
set
não é estruturada, o que significa que qualquer variável que contenha uma nova linha pode contaminar totalmente os resultados.Isso, é claro, é um risco potencial à segurança. Em vez disso, use o suporte do Bash para expansão de nome de variável indireta ou
compgen -v
.fonte
Experimente o seguinte:
set | egrep "^\w+="
(com ou sem o| less
tubulação)A primeira solução proposta,,
( set -o posix ; set ) | less
funciona, mas tem uma desvantagem: ela transmite códigos de controle para o terminal, de modo que eles não são exibidos corretamente. Então, por exemplo, se houver (provavelmente) umaIFS=$' \t\n'
variável, podemos ver:…em vez de.
Minha
egrep
solução exibe isso (e eventualmente outros semelhantes) corretamente.fonte
bash -c $'a() { echo "\nA=B"; }; unset A; set | egrep "^\w+="' | grep ^A
exibições erradasA=B"
-> Falha!Provavelmente roubei a resposta há algum tempo ... de qualquer maneira, um pouco diferente em função:
fonte
O
printenv
comando:printenv
imprimeenvironment variables
junto com seus valores.Boa sorte...
fonte
Uma maneira simples de fazer isso é usar o modo estrito bash definindo as variáveis de ambiente do sistema antes de executar seu script e usar diff para classificar apenas as do seu script:
Agora você pode recuperar variáveis de seu script em /tmp/script_vars.log. Ou pelo menos algo baseado nisso!
fonte
Um pouco tarde para a festa, mas aqui vai outra sugestão:
A linha de comando do pipeline diff + sed exibe todas as variáveis definidas pelo script no formato desejado (conforme especificado na postagem do OP):
fonte