O comando bash builtin set
, se chamado sem argumentos, imprimirá todas as variáveis de shell e ambiente, mas também todas as funções definidas. Isso torna a saída inutilizável para humanos e difícil grep
.
Como posso fazer com que o comando bash builtin set
imprima apenas as variáveis e não as funções?
Existem outros comandos que imprimem apenas as variáveis do shell, sem as funções?
Nota: o bash diferencia entre variáveis de shell e variáveis de ambiente. veja aqui Diferença entre variáveis de ambiente e variáveis de ambiente exportadas no bash
fonte
_
, que são fáceis de se livrar de:(set -o posix ; set | grep -v ^_)
set -o posix; set | sed -e '/^_/,$d'; set +o posix;
(set -o posix; set)
. Sem os colchetes, o comportamento do shell Bash atual seria alterado para corresponder ao padrão Posix. (Não sei o que isso significa, mas parece importante.) Com os colchetes, o Bash permanece inalterado.POSIXLY_CORRECT=y
e adicionaposix
a$SHELLOPTS
Aqui estão algumas soluções alternativas:
demolir:
declare
imprime todas as variáveis definidas (exportadas ou não) e funções.declare -f
imprime apenas funções.comm -3
removerá todas as linhas comuns a ambos. Com efeito, isso removerá as funções, deixando apenas as variáveis.Para imprimir apenas variáveis que não são exportadas:
Outra solução alternativa:
Isso imprimirá apenas as variáveis, mas com alguns atributos feios.
Você pode cortar os atributos usando ... cut:
Uma desvantagem é que o valor do IFS é interpretado em vez de exibido.
comparar:
Isso torna bastante difícil usar essa saída para processamento adicional, por causa disso isolado
"
em uma linha. Talvez algum IFS-fu possa ser feito para evitar isso.Outra solução alternativa, usando
compgen
:O bash interno
compgen
foi criado para ser usado em scripts de conclusão. Para esse fim,compgen -v
lista todas as variáveis definidas. A desvantagem: lista apenas os nomes das variáveis, não os valores.Aqui está um hack para listar também os valores.
A vantagem: é uma solução pura para o bash. A desvantagem: alguns valores são confusos por causa da interpretação
printf
. Além disso, o subshell do pipe e / ou loop adiciona algumas variáveis extras.fonte
declare ...| cut
pipe quebra se não houver atributos para uma variável? Acho que--
é usado nesse caso, mas ainda estou desconfortável.sed
pode ser mais seguro, iedeclare -p | sed 's/^.* \([^ ]\+\)$/\1/'
compgen
:)O
typeset
builtin estranhamente tem uma opção para mostrar apenas funções (-f
), mas não para mostrar apenas parâmetros. Felizmente,typeset
(ouset
) exibe todos os parâmetros antes que todas as funções, funções e nomes de parâmetros não possam conter novas linhas ou sinais de igual, e as novas linhas nos valores dos parâmetros sejam citadas (elas aparecem como\n
). Portanto, você pode parar na primeira linha que não contém um sinal de igual:Isso imprime apenas os nomes dos parâmetros; se você deseja os valores, mude
print $1
paraprint $0
.Observe que isso imprime todos os nomes de parâmetros (parâmetros e variáveis são usados como sinônimos aqui), não apenas variáveis de ambiente ("variável de ambiente" é sinônimo de "parâmetros exportados").
Observe também que isso pressupõe que não há variável de ambiente com um nome que não corresponda às restrições do bash nos nomes de parâmetros. Tais variáveis não podem ser criadas dentro do bash, mas podem ter sido herdadas do ambiente quando o bash é iniciado:
fonte
set | sed '/=/!Q'
Não tenho certeza de como se pode
set
imprimir variáveis apenas. No entanto, olhando para a saída deset
, eu consegui criar o seguinte que parece pegar apenas variáveis:Basicamente, estou procurando linhas que começam com letras, números ou pontuação seguidas por um "=". Da saída que eu vi, isso pega todas as variáveis; no entanto, duvido que isso seja muito portátil.
Se, como o título sugere, você deseja subtrair desta lista as variáveis que são exportadas e, assim, obter uma lista de variáveis não exportadas, poderá fazer algo assim
Para resumir um pouco, aqui está o que ele faz:
set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" | sort > ./setvars
: Esperamos que isso obtenha todas as variáveis (como discutido anteriormente), classifique-as e cole o resultado em um arquivo.&& env | sort
: Após a conclusão do comando anterior, vamos chamarenv
e classificar sua saída.| comm -23 ./setvars -
: Finalmente, canalizamos a saída classificada deenv
paracomm
e usamos a-23
opção para imprimir as linhas que são únicas para o primeiro argumento; nesse caso, as linhas exclusivas para nossa saída do conjunto.Quando terminar, você pode limpar o arquivo temporário que ele criou com o comando
rm ./setvars
fonte
f () {|cat <<EOF|foo=bar|EOF|}
onde|
representa uma quebra de linha).Basta usar o comando
env
. Não imprime funções.fonte
Experimente o comando printenv:
fonte
No bash, isso imprimirá apenas nomes de variáveis:
Ou, se também forem necessários valores, use:
fonte
diferindo de um shell limpo para garantir também que vários dos scripts rc sejam deixados de fora
a versão com
comm
seria muito complicadafonte
A resposta aceita é ótima. Estou oferecendo uma alternativa que não envolve a configuração do modo POSIX:
Aqui está a técnica que eu tenho usado para armazenar o estado da função em um arquivo para que eu possa continuar mais tarde. O primeiro produz um despejo de estado e o segundo produz apenas uma lista dos nomes das variáveis.
Ambos funcionam despejando linhas até encontrar um sem um caractere '=', o que ocorre quando a primeira função é listada. O último corta a tarefa.
fonte