Problem
When using tkInfra.NewShell with the Username field to run commands as a different user, the parent process's environment leaks into the child process. This happens because prepareExec() inherits the parent env via execCmd.Environ() (line 140 of shell.go):
execCmd.Env = append(execCmd.Environ(), "DEBIAN_FRONTEND=noninteractive")
execCmd.Env = slices.Concat(execCmd.Env, shell.runtimeSettings.Envs)
When the parent runs as root (HOME=/root) and we pass HOME=/home/username in Envs, both entries exist in the env slice. Since getenv() returns the first match, the parent's HOME=/root takes precedence — the appended value is never seen.
This breaks rootless podman (and likely other user-scoped tools) because they resolve config paths from HOME:
faccessat /root/.config/containers/storage.conf: permission denied
Proposed Solution
Add a ShouldUseCleanEnv boolean to ShellSettings. When set to true, skip the execCmd.Environ() inheritance and build execCmd.Env solely from ShellSettings.Envs (plus the automatic DEBIAN_FRONTEND=noninteractive):
if shell.runtimeSettings.ShouldUseCleanEnv {
execCmd.Env = []string{"DEBIAN_FRONTEND=noninteractive"}
} else {
execCmd.Env = append(execCmd.Environ(), "DEBIAN_FRONTEND=noninteractive")
}
execCmd.Env = slices.Concat(execCmd.Env, shell.runtimeSettings.Envs)
This is backward-compatible — the default (false) preserves the current behavior.
Context
Discovered while migrating EZ's RunCmdAsUser to use tkInfra.NewShell. The function runs commands as a different system user and needs a clean environment with explicit HOME, XDG_RUNTIME_DIR, DBUS_SESSION_BUS_ADDRESS, etc. Without a clean-env option, we can't use tk Shell for this use case.
Problem
When using
tkInfra.NewShellwith theUsernamefield to run commands as a different user, the parent process's environment leaks into the child process. This happens becauseprepareExec()inherits the parent env viaexecCmd.Environ()(line 140 ofshell.go):When the parent runs as root (
HOME=/root) and we passHOME=/home/usernameinEnvs, both entries exist in the env slice. Sincegetenv()returns the first match, the parent'sHOME=/roottakes precedence — the appended value is never seen.This breaks rootless podman (and likely other user-scoped tools) because they resolve config paths from
HOME:Proposed Solution
Add a
ShouldUseCleanEnvboolean toShellSettings. When set totrue, skip theexecCmd.Environ()inheritance and buildexecCmd.Envsolely fromShellSettings.Envs(plus the automaticDEBIAN_FRONTEND=noninteractive):This is backward-compatible — the default (
false) preserves the current behavior.Context
Discovered while migrating EZ's
RunCmdAsUserto usetkInfra.NewShell. The function runs commands as a different system user and needs a clean environment with explicitHOME,XDG_RUNTIME_DIR,DBUS_SESSION_BUS_ADDRESS, etc. Without a clean-env option, we can't use tk Shell for this use case.