posix shell: lista de impressão de nomes de variáveis de ambiente (sem valores)

8

De uma maneira compatível com posix que funciona com várias implementações, como posso imprimir a lista de variáveis de ambiente atualmente definidas sem seus valores?

Em algumas implementações (mksh, freebsd / bin / sh), usar apenas export por si só se encaixará na fatura:

$ export
FOO2
FOO

Mas para algumas outras implementações (bash, zsh, dash), export também mostra o valor. Com bash, por exemplo:

$ export
export FOO2='as  df\
  asdk=fja:\
asd=fa\
asdf'
export FOO='sjfkasjfd  kjasdf:\
   asdkj=fkajdsf:\
       :askjfkajsf=asdfkj:\
   safdkj'
$ printenv | sed -n l
FOO2=as\tdf\$
  asdk=fja:\$
asd=fa\$
asdf$
FOO=sjfkasjfd  kjasdf:\$
   asdkj=fkajdsf:\$
\t:askjfkajsf=asdfkj:\$
   safdkj$

Outras opções como env ou printenv não têm opções para imprimir apenas os nomes das variáveis sem valores, pelo menos não nas plataformas linux e freebsd que eu tentei.

Tubulação para awk / sed / etc. ou aparar a lista com técnicas de expansão de parâmetro (por exemplo, ${foo%%=*} ) é aceitável, mas precisa trabalhar com valores que podem abranger linhas e ter = e espaço em branco no valor (consulte o exemplo acima).

Respostas específicas para implementações específicas de shell são interessantes, mas eu estou principalmente procurando por algo que seja compatível com implementações.

    
por Juan 21.04.2018 / 17:41

1 resposta

6

É bem fácil no awk.

awk 'BEGIN{for(v in ENVIRON) print v}'
No entanto, algumas implementações do awk adicionam variáveis de ambiente próprias (por exemplo, o GNU awk adiciona AWKPATH e AWKLIBPATH a ENVIRON ).

A saída é ambígua se o nome de uma variável de ambiente contiver uma nova linha, o que é extremamente incomum, mas tecnicamente possível. Uma solução sh pura seria difícil. Sua melhor aposta é começar com export -p mas massagear em sh puro é difícil. Você pode usar sed para massagear a saída de export -p e usar eval para obter o shell para remover o que foi citado. Bash e zsh imprimem prefixos não padrão.

report () { echo "${1%%=*}"; };
eval "$(export -p | sed "s/^export /report /;
                         s/^declare -x /report /;
                         s/typeset -x /report /")"

Observe que, dependendo do shell, export -p pode ou não mostrar variáveis cujo nome não é válido no shell e, se não, pode ou não citar os nomes corretamente. Por exemplo, dash, mksh e zsh omitem variáveis cujo nome inclui uma nova linha, BusyBox traço e ksh93 imprima-os em bruto, e o bash os imprime sem seu valor. Se você precisa se defender contra entradas não confiáveis, não confie em uma solução POSIX pura, e definitivamente não chame eval em nada derivado da saída de export -p .

    
por 21.04.2018 / 22:34