Skip to content
shellhacks.dev
Linux

Run a command with a clean environment

Run a command with an empty environment using env -i, then add back only the variables you pass. It reproduces what cron or a minimal container sees.

1 min read
Summarize in AI

A script works in your terminal and fails in cron, and the difference is the environment it inherits.

Shell
export SECRET_TOKEN=abc123
env -i /usr/bin/env | wc -l
env -i A=1 B=2 /usr/bin/env
env -i sh -c 'echo "PATH is [$PATH], HOME is [${HOME-unset}]"'
Text
0
A=1
B=2
PATH is [/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin], HOME is [unset]

env -i (--ignore-environment) starts the command with an empty environment, and NAME=value words before the command add variables back, as the coreutils manual describes. The first run prints zero lines, so the exported SECRET_TOKEN did not leak into the child. The last line shows that Debian's dash invents a default PATH but not a HOME.

Different shells fill in different defaults for what you removed, so a script that works under env -i bash can still fail under env -i dash. Add the variables the job really gets from cron, PATH, HOME, LOGNAME, SHELL, to the test, otherwise it is stricter than the real thing.

Share

More snippets

Linux

Get a process's command line

Read a running process's full command line from /proc/PID/cmdline. The arguments are separated by NUL bytes, so split them with xargs -0 and not tr.

1 min read
Linux

Always use -a with -G

Add a user to a group with usermod -aG. Without -a the -G option replaces the whole supplementary group list, and the user silently loses every other group.

1 min read
Linux

Convert a date string to a timestamp

Convert a date string to a Unix timestamp with GNU date -d 'string' +%s. The zone is the one in TZ unless the string names one, so set it explicitly.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.