Environment Variables
Learn how to read and set environment variables in Perl through the %ENV hash, and why this matters for scripting.
Introduction
Scripts rarely run in isolation - they inherit context from the operating system in the form of environment variables: things like the current user's home directory, the search path for executables, or application-specific configuration set by whoever launched the script. Perl exposes all of this through a single hash: %ENV.
- What environment variables are and where they come from.
- How to read them safely through %ENV.
- How to set them, and what that does (and does not) affect.
- Why environment variables matter for configuration and automation.
What Are Environment Variables?
Environment variables are key-value pairs maintained by the operating system for each running process. A process inherits its environment from whatever launched it (a shell, a cron job, a CI system), and can read that environment to change its own behavior without hardcoding configuration into the script itself.
The %ENV Hash
Perl automatically populates the special hash %ENV with a copy of the process environment when it starts. Every environment variable becomes a key, and its value becomes the corresponding hash value - all standard Perl hash operations work on it.
use strict;use warnings;
print "Home directory: $ENV{HOME}\n" if exists $ENV{HOME};print "Path: $ENV{PATH}\n" if exists $ENV{PATH};Click Run to see what this code prints.
Reading Environment Variables Safely
Not every variable you might expect is guaranteed to exist - HOME, for instance, is a Unix convention and may be missing or named differently on Windows (USERPROFILE). Always check with exists, or provide a fallback with the defined-or operator //, before relying on a value.
Common Variables You Will See
| Variable | Typical Meaning |
|---|---|
| PATH | Directories searched for executable programs |
| HOME / USERPROFILE | The current user's home directory (Unix / Windows) |
| USER / USERNAME | The name of the current user (Unix / Windows) |
| LANG | The system's locale and language setting |
| TEMP / TMP | The directory for temporary files |
| PERL5LIB | Extra directories Perl should search for modules |
Setting Environment Variables
You can assign directly into %ENV. This changes the environment for the current process and anything it launches afterward, but it never reaches back out to the shell or process that started your script - that inheritance only flows one direction, from parent to child.
use strict;use warnings;
$ENV{MY_APP_MODE} = 'production';system($^X, '-e', 'print "Mode inside child: $ENV{MY_APP_MODE}\n"');Click Run to see what this code prints.
Environment Variables and Child Processes
Child processes started with system, exec, or backticks inherit a copy of %ENV as it looks at the moment they start. If you only need a change temporarily - for one block of code - use local so the original value is automatically restored afterward.
use strict;use warnings;
sub run_with_debug { local $ENV{DEBUG} = 1; system($^X, '-e', 'print "DEBUG=$ENV{DEBUG}\n"');}
run_with_debug();print "DEBUG outside: ", ($ENV{DEBUG} // 'unset'), "\n";Click Run to see what this code prints.
A Practical Example
A very common pattern is letting an environment variable override a default configuration value - useful for pointing a script at different config directories in development versus production without editing code.
use strict;use warnings;
my $config_dir = $ENV{APP_CONFIG_DIR} // '/etc/myapp';print "Using config directory: $config_dir\n";Click Run to see what this code prints.
Common Mistakes
- Assuming a variable like HOME always exists, then getting undef warnings when it does not.
- Expecting a change to %ENV to affect the terminal or shell that launched the script - it never does.
- Forgetting that changes to %ENV are permanent for the rest of the process unless you use local.
- Ignoring case-sensitivity differences - Windows environment variable names are effectively case-insensitive, while %ENV keys in Perl are still ordinary case-sensitive hash keys.
Best Practices
- Use exists or the // operator to provide sensible defaults for optional environment variables.
- Use local $ENV{...} inside a block or subroutine when a change should only be temporary.
- Document which environment variables your script expects, and what they default to.
- Never log or print environment variables that might contain secrets, such as API keys or passwords.
Frequently Asked Questions
No. Each process has its own private copy of the environment; changes are visible only to your process and any children it starts afterward.
The underlying mechanism is the same, but the specific variable names differ - for example USERPROFILE instead of HOME - and Windows treats variable names case-insensitively at the OS level.
Yes, with delete $ENV{VARNAME}, which removes it for the current process and any children started afterward.
Key Takeaways
- %ENV is a normal Perl hash populated from the process environment at startup.
- Always check for existence or provide a default before relying on an environment variable.
- Assignments to %ENV only affect the current process and its future children.
- Use local $ENV{...} for changes that should be automatically undone.
Summary
Environment variables are how scripts stay configurable without hardcoding values, and %ENV makes them trivial to read and set in Perl. Next, you will put many of these tools together to write practical system administration scripts.