Skip to main content
3 of 3
added 1046 characters in body
Gilles 'SO- stop being evil'
  • 866.5k
  • 205
  • 1.8k
  • 2.3k

It's pretty easy in awk.

awk 'BEGIN{for(v in ENVIRON) print v}' 

However beware some awk implementations add environment variables of their own (e.g. GNU awk adds AWKPATH and AWKLIBPATH to ENVIRON).

The output is ambiguous if the name of an environment variable contains a newline, which is extremely unusual but technically possible. A pure sh solution would be difficult. Your best bet is to start with export -p but massaging it in pure sh is difficult. You can use sed to massage the output of export -p, then use eval to get the shell to remove what it quoted. Bash and zsh print non-standard prefixes.

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

Note that depending on the shell, export -p may or may not show variables whose name is not valid in the shell, and if it doesn't, then it may or may not quote the names properly. For example, dash, mksh and zsh omit variables whose name includes a newline, BusyBox dash and ksh93 print them raw, and bash prints them raw without their value. If you need to defend against untrusted input, don't rely on a pure POSIX solution, and definitely don't call eval on anything derived from the output of export -p.

Gilles 'SO- stop being evil'
  • 866.5k
  • 205
  • 1.8k
  • 2.3k