In unix, the environment is passed from a parent process to a child process. The parent process has complete control of the child's initial environment. By default, the child inherits the parent's environment, but the parent can pass something completely different, and the child can change it afterwards. As such, there is no "global" environment. There is an "initial" environment, but no global environment.
So, if nothing is explicitly set, the environment is inherited from whatever parent process last set it before forking.
Every operating system (and every distro) handles setting the initial environment differently. Since this is asking about Ubuntu, I'll limit things to that.
In Ubuntu, systemd starts the first processes, and has control of that initial environment. Systemd chooses to not have a way to set a global default environment within itself, but it has provisions for setting variables in different contexts.
- systemd-environment-d-generator sets initial environment for user manager instances.
- systemd.environment-generator has separate config files for each manager service
- pam_env.conf modifies the environment for users that log in (see man pages for environ(7) and pam_env.conf)
- For bash and sh,
/etc/environment
can set variables when the shell starts; these can be inherited by subprocesses. Most shell instances read this, but some don't, and they can be explicitly told not to.
- Each shell can read
/etc/profile
or /etc/bash.bashrc
which in turn may read files from /etc/profile.d
, but again, not every shell instance does this, and the shell can be told to not read these or only read these.
- Each user's shell init files can modify the environment.
- Programs like
ssh
and sudo
have whitelists and blacklists of variables that are intentionally inherited or intentionally removed for subprocesses.
- Services like systemd and cron typically inherit and pass a very minimal set of environment variables. Cron allows setting variables in each config file that are "global" for that config file.
- The
env
command can modify the environment of a command before it is started.
This list is not exhaustive, there are probably more sources.
And none of these are "global" -- environment variables are explicitly local to each process, although they can be inherited from a global source.