539

How to list all variables names and their current values?

Including not only $HOME, $PWD etc but any other you have defined.

7ochem
  • 191
Strapakowsky
  • 11,914
  • 5
    http://superuser.com/questions/420295/how-do-i-see-a-list-of-all-currently-defined-environment-variables-in-a-linux-ba – Ciro Santilli OurBigBook.com Nov 30 '15 at 14:46
  • 9
    You've accepted an incorrect answer. "printenv" only gives you the environment variables. If you truly want all variables currently declared in your shell, use "declare -p" or "typeset -p". – Florin Andrei Jul 26 '19 at 19:11

11 Answers11

712

For bash: (the standard shell in Ubuntu)

Enter the following command in a terminal to print all the environment variables:

printenv

For further information about this command, read the printenv man page.


To show a list including the "shell variables" you can enter the next command:

( set -o posix ; set ) | less

This will show you not only the shell variables, but the environment variables too.

For more information related with this topic read:


For zsh: (an advanced shell)

Use the following command:

( setopt posixbuiltin; set; ) | less

For more information about ZSH options, see zshoptions man page.

Fabby
  • 34,259
Lucio
  • 18,843
  • 21
    If I go to the terminal and write MYNEWVARIABLE=Ubuntu and execute printenv it doesn't show there. Why is that, and how do those others show up? – Strapakowsky Mar 30 '13 at 03:30
  • 8
    Probably you are seeing the difference between a shell variable and an environment variable. Try export MYNEWVARIABLE=Ubuntu and it will work as you expect. – Rmano Oct 12 '13 at 00:41
  • 5
    if you simply execute set, it lists the variable created by you as well. Or do set | grep myvar – Sergiy Kolodyazhnyy Jan 04 '15 at 15:01
  • 8
    printenv is an external command, so it only knows about (and prints) exported environment variables. set is an internal bash command, so it shows all the "shell variables" (unexported environment variables) as well as the exported environment variables. – Dan Pritts Jul 30 '15 at 15:33
  • Works on OSX too – Craig Wayne Apr 05 '16 at 07:52
  • 2
    To expand on @Rmano's reply to @Strapakowsky... This will not work unset MYNEWVARIABLE; MYNEWVARIABLE=Ubuntu; printenv | grep MYNEW, but this will unset MYNEWVARIABLE; export MYNEWVARIABLE=Ubuntu; printenv | grep MYNEW, and this will unset MYNEWVARIABLE; MYNEWVARIABLE=Ubuntu printenv | grep MYNEW. Using export says "the variable I'm setting should be part of the environment that gets passed to processes, not just a variable in this shell." My third example says "the variable should be part of the environment that gets passed to THIS process, but not stick around afterward." – Bruno Bronosky Aug 26 '16 at 17:39
  • 2
    -o posix is bash only, not for sh – Dereckson Feb 19 '18 at 16:35
  • 2
    This is incorrect. env or printenv only print environment variables. To get ALL VARIABLES declared in your current shell, use "declare -p" or "typeset -p". See another answer on this page. – Florin Andrei Jul 26 '19 at 19:08
  • I like this answer for Bash, but the POSIX set omits some shell variables. You can get them all with declare -p | while read -r _ flags line; do printf "%s\n" "$line"; done. – Colin Fraizer May 18 '20 at 21:29
  • FWIW, I discovered this using: diff <( set -o posix; set | while read -r line; do printf "%s\n" "${line%%=*}"; done | sort) <(declare -p | while read -r _ flags line; do printf "%s\n" "${line%%=*}"; done | sort) to compare the outputs of each. Omitted variables were: BASHPID, BASH_ARGV0, EPOCH{REALTIME,SECONDS}, FUNCNAME, HISTCMD, LINENO, OLDPWD, RANDOM, and SECONDS. – Colin Fraizer May 18 '20 at 21:33
110

You can see all variables with the declare builtin.

declare -p

If you're only interested in environment variables, use

declare -xp

Run help declare to see what the other options are.

geirha
  • 46,101
  • 5
    this is far neat-er solution than POSIXLY_CORRECT=1 set and it is also worthy of mention that declare is alias (in that context) for typeset, another bash builtin. –  Feb 07 '18 at 16:50
  • 5
    This is the correct answer. – Florin Andrei Jul 26 '19 at 19:11
  • 3
    I think this is what most people are looking for. – WinEunuuchs2Unix Oct 18 '19 at 23:56
  • for the sake of convenience the following bash oneliner prints names of all environment variables: declare -xp | grep --perl-regexp --only-match '(?<=^declare -x )[^=]+' – maoizm Feb 02 '20 at 07:25
  • 4
    @maoizm If you want only the variable names and nothing else, it's easier to use compgen for that. compgen -e. – geirha Feb 03 '20 at 20:33
  • Works in ZSH too, thank you! – Alexey Vazhnov Apr 19 '20 at 10:53
  • A useful addition, if you just want just the names and not the values: declare -p | while read -r _ flags line; do printf "%s\n" "${line%%=*}"; done. (Variables with values that contain embedded newlines, e.g. IFS, will add a blank line.) – Colin Fraizer May 18 '20 at 21:42
  • 1
    @ColinFraizer try compgen -v instead – geirha May 20 '20 at 06:32
  • 1
    That is nice. Thanks! (Oddity: when called from top level—not within a function—declare -p includes FUNCNAME, but compgen -v does not. When called within a function, the output is identical.) – Colin Fraizer May 22 '20 at 13:55
  • In zsh, use declare -p1 to prettify the printed variables for readability – smac89 Dec 21 '20 at 04:27
  • What if I want all variables except the environment? – Velkan Jan 13 '22 at 07:49
  • @Velkan that's a bit harder as there's no option with either declare or compgen that lists all but env vars, but you can get that list of variable names by grabbing all variable names (compgen -v) and removing the environment variables (compgen -e) from that. E.g. with comm -23 <(compgen -v) <(compgen -e) – geirha Jan 13 '22 at 13:29
  • declare -f prints all functions. declare -F prints all function names and their export status. declare -f someFunction prints some function – milahu Feb 09 '24 at 18:26
66

I know that this question is quite old and answered, but I think I can add a bit of useful information.

In all the methods described above, the procedure that is suggested is:

  • launch a terminal
  • show the environment variables using env, or printenv or whatever

The problem of these solutions are that you are seeing the environment variables of the shell that is running into the terminal. You are not seeing the environment variables available to an application run, for example, directly by the graphic interface.

This is noticeable if, for example, you use your ~/.profile, or .bashrc, or .zshenv (depending on your shell) to modify the environment variables --- like the classic addition of directories to the path.

To see the environment variables available to the application started directly in the graphic environment, you can do the following (in Gnome Shell, I am sure there is an equivalent method in all the other DE):

  • press Alt-F2
  • run the command xterm -e bash --noprofile --norc

(Or, if you do not have xterm, gnome-terminal -- bash --noprofile --norc --- thanks to @Mike Nakis for the comment).

You now have a terminal with a shell that did not add any environment variables. You can use env here to list all your environment variables:

Example of the bare shell

Obviously the new shell will have the environment variables added by the system files, but that variables should be available (by inheritance) to all programs in the system anyway.

I am posting this because it's the fourth time I have to search this trick again, checking my .pam_environment file. So now I will find it faster (and in the process, I hope helping someone else...)

Rmano
  • 31,947
  • Requires you have a desktop environment, not useful for server CLI-only folk. – K7AAY Oct 21 '13 at 18:21
  • 7
    Yes --- but then for CLI only the previous answer is ok. I was just pointing out that sometime you need to check environment variables available to application started by the graphical environment, which is not the same set you see when you start a terminal in it. For example, if you are trying to understand why your Kile app can't compile a LaTeX file, while in a terminal you can, the trick I posted here will help a lot. – Rmano Oct 21 '13 at 20:36
  • 4
    Thanks for a very useful answer! I just linked to it from https://help.ubuntu.com/community/EnvironmentVariables#Desktop_environment_specifics – Gunnar Hjalmarsson Jan 02 '14 at 17:06
  • Thanks. Did you recommend xterm -e bash --noprofile --norc because the startup files are not read and executed when Ubuntu is started with graphical interface ? See https://askubuntu.com/q/1025845/1471 – Tim Apr 17 '18 at 14:49
  • @Tim basically it's just a way to have a shell without anything more than the environment variables available to the graphic environment. A standard terminal will read (or re-read) .bashrc for example... – Rmano Apr 17 '18 at 15:06
  • 2
    the right command to execute nowadays (Ubuntu 18.04) is gnome-terminal -- bash --noprofile --norc – Mike Nakis Apr 28 '19 at 11:10
  • But what if the graphic application changed it‘s environment variables (e.g. due some settings)? Isn‘t there a way to check out the actual environment variables of any process by it‘s PID? – Arber May 04 '23 at 20:25
  • @Arber I think that's worth a new question.... – Rmano May 04 '23 at 20:44
17

In bash using compgen:

compgen -v | while read line; do echo $line=${!line};done  
Seth
  • 58,122
tmgoblin
  • 179
  • 1
  • 2
  • 3
    This should be the accepted answer, as all others list more than just the name itself. In my case some variables contain multiline values which makes the other solutions not feasable. – Mene Nov 09 '17 at 15:20
  • 3
    A variant: compgen -v | while read line; do declare -p $line; done – Eljay Dec 13 '18 at 17:58
  • @Eljay what is the difference to just declare -p? – DJCrashdummy Jun 15 '23 at 08:13
  • @DJCrashdummy • declare -p won't include things like BASH_COMMAND, BASH_SUBSHELL, COMP_WORDBREAKS, HISTCMD, LINENO, RANDOM, SECONDS. – Eljay Jun 15 '23 at 11:05
  • @Eljay well... at least for me declare -p "includes" resp. lists them all (and FUNCNAME additionally), but you are kind of right: the values are not shown and also values of arrays are not shown. do you know why this is? -- so IMHO your line is the most comprehensive way to do this, even with all values of arrays including indexes! – DJCrashdummy Jun 22 '23 at 10:53
  • @DJCrashdummy • I don't know why that is. My guess is the programmer for those things did not think it was useful, and hence the various strategies (or workarounds) to get that information. – Eljay Jun 22 '23 at 11:49
16

To list the environment variables in terminal with CTRL+ALT+T you can use env command.

for example :

[raja@localhost ~]$ env
XDG_VTNR=1
SSH_AGENT_PID=3671
XDG_SESSION_ID=3
HOSTNAME=localhost.localdomain
IMSETTINGS_INTEGRATE_DESKTOP=yes
GPG_AGENT_INFO=/home/raja/.gnupg/S.gpg-agent:3691:1
GLADE_PIXMAP_PATH=:
TERM=xterm-256color
SHELL=/bin/bash
XDG_MENU_PREFIX=xfce-
DESKTOP_STARTUP_ID=
HISTSIZE=1000
XDG_SESSION_COOKIE=0250277dd805498381e96c05d88068b0-1364679772.845276-1676152201
WINDOWID=65011716
GNOME_KEYRING_CONTROL=/home/raja/.cache/keyring-N3QoQ2
IMSETTINGS_MODULE=none
QT_GRAPHICSSYSTEM_CHECKED=1
USER=raja

etc.

hope that helps.

Raja G
  • 102,391
  • 106
  • 255
  • 328
  • I've noticed that env misses some variables o_O. specifically after sourcing a VAR=VAL file. – ThorSummoner Aug 02 '17 at 19:43
  • 3
    @ThorSummoner The answer here might help https://stackoverflow.com/questions/15474650/unix-what-is-the-difference-between-source-and-export – georaldc Aug 14 '17 at 17:48
9

Most solutions here either print only environment variables, or have the drawback that env or (set -o posix; set) do not print values in easily parseable form (try to print variable A=$'a\r\nb', it has multiple lines...).

Here is a function that will print all variables, one variable per line, in the POSIX escaped form (works properly for simple text variables, does not work for arrays):

function dump_vars {
    local VARNAME
    compgen -v | while read -r VARNAME; do
        printf "$VARNAME=%q\n" "${!VARNAME}"
    done
}

Thanks to @tmgoblin for pointing out the use of compgen -v.

7

If you want a specific environment variable, rather than printing them all with printenv, you can for example print it by doing echo "$PWD"

inigo333
  • 171
  • The quotes are unnecessary; i.e.: echo $PATH or echo $USER. This will print the environment variable's value. The dollar sign operator is the only thing needed to access the value of a variable or command. – NOCARRIER Jun 08 '23 at 19:42
4
  • printenv will show all the global environoment variables
  • env, global environment variable after login modification
  • set, will display all local environment variable, relative to the session (usually the local var is the global + the particular of the session)
kelvinelove
  • 1,617
  • 1
  • 16
  • 26
4

env is a POSIX 7 way:

export asdf=qwer
env | grep asdf

Sample output:

asdf=qwer

It only shows exported variables: non-exported variables are not usually considered "environment variables".

Prefer that over printenv, which is not POSIX. Both seem to do the same thing without arguments: https://unix.stackexchange.com/questions/123473/what-is-the-difference-between-env-and-printenv

1

printenv only lists exported variables, command+alt+$ ( "\e$": complete-variable ) will list all variables.

1

Script to dump everything, sort, and highlight all $ENVS and $variables declared in the session.

#!/bin/bash
temp="$(mktemp)"
declare > $temp
printenv >> $temp;
sort -u $temp -o $temp;
grep --color=auto -E '^[A-Za-z_]+[^=]+' $temp 
rm -i $temp