En pocas palabras:set puede ver variables locales de shell, env no puede.
Los shells pueden tener variables de 2 tipos:locales, a las que solo se puede acceder desde el shell actual, y variables de entorno (exportadas), que se pasan a cada programa ejecutado.
Desde set es un incorporado comando de shell, también ve variables locales de shell (incluidas las funciones de shell). env por otro lado es un ejecutable independiente; solo ve las variables que le pasa el shell, o variables de entorno.
Cuando escribes una línea como a=1 luego se crea una variable local (a menos que ya existiera en el entorno). Las variables de entorno se crean con export a=1
Si desea limitar la salida del set comando solo para variables, puede ejecutarlo en modo POSIX:
type -a env set
help set
(set -o posix; set) | nl
Si necesita un control más preciso sobre la lista de variables específicas, puede usar las funciones integradas de Bash como declare o compgen , o algunos otros trucos de Bash.
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
set es un shell incorporado, mientras que env es un programa (/usr/bin/env)
set hace varias cosas, pero por sí mismo enumera las variables de entorno. También puede configurar/alternar interruptores, como set +x o set -v etc.
env por sí mismo enumera los exportados variables de entorno, pero puede ejecutar un programa en un entorno modificado
Ver man 1 env para más información.