What's the difference between "env" and "set" (on Mac OS X or Linux)?

LinuxBashMacosEnvironment Variables

Linux Problem Overview


I get similar results running "env" and "set". Set gives more results - is it a superset of env?

The man page for set doesn't give any information. How do these commands work and what's the difference?

Linux Solutions


Solution 1 - Linux

Long story short: set can see shell-local variables, env cannot.

Shells can have variables of 2 types: locals, which are only accessible from the current shell, and (exported) environment variables, which are passed on to every executed program.

Since set is a built-in shell command, it also sees shell-local variables (including shell functions). env on the other hand is an independent executable; it only sees the variables that the shell passes to it, or environment variables.

When you type a line like a=1 then a local variable is created (unless it already existed in the environment). Environment variables are created with export a=1

Solution 2 - Linux

If you want to limit the output of the set command to variables only, you may run it in POSIX mode:

type -a env set
help set
(set -o posix; set) | nl

If you need finer control over listing specific variables, you may use Bash builtins such as declare or compgen, or some other Bash tricks.

man bash | less -p '-A action$'  # info on complete & compgen

# listing names of variables
compgen -A variable | nl       # list names of all shell variables
echo ${!P*}                    # list names of all variables beginning with P

compgen -A export | nl         # list names of exported shell variables
export | nl                    # same, plus always OLDPWD
declare -px | nl               # same

declare -pr                    # list readonly variables
                   
# listing names of functions           
compgen -A function | nl
declare -F | nl
declare -Fx | nl

# show code of specified function
myfunc() { echo 'Hello, world!'; return 0; }
declare -f myfunc  

Solution 3 - Linux

set is a shell builtin, while env is a program (/usr/bin/env)

set does several things, but by itself it lists the environment variables. It can also set/toggle switches, such as set +x or set -v etc.

env by itself lists the exported environment variables, but can run a program in a modified environment

See man 1 env for more information.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionstupakovView Question on Stackoverflow
Solution 1 - LinuxintgrView Answer on Stackoverflow
Solution 2 - LinuxtimView Answer on Stackoverflow
Solution 3 - LinuxStephen PView Answer on Stackoverflow