Skip to content

bug: BASH_ENV / $ENV not sourced for non-interactive non-login shells (returns "not yet implemented") #1130

Description

@melderan

Summary

When BASH_ENV (or ENV in --sh mode) is set in the environment, brush returns an "unimplemented" error instead of sourcing the named file, breaking non-interactive -c invocations.

Reproduction

echo 'echo loaded' > /tmp/empty.sh
BASH_ENV=/tmp/empty.sh brush -c 'echo hello'

Expected:

loaded
hello

Actual:

error: not yet implemented: load config from $ENV/BASH_ENV for non-interactive, non-login shell

Workaround: pass --noenv.

Why this matters

It's common for users to have BASH_ENV exported from their login profile (e.g., to point at a shared init script for non-interactive bash). Once BASH_ENV is set, every non-interactive brush -c invocation fails. That makes brush hard to use as a drop-in bash -c replacement from other tools (CI runners, editor "run shell command" features, parent processes that exec a shell to run a one-liner) without surgery on the caller's environment.

Source

The bailout is at brush-core/src/shell/initscripts.rs and is already TODO'd:

// TODO(well-known-vars): look at $ENV/BASH_ENV; source its expansion if that
// file exists
return error::unimp(
    "load config from $ENV/BASH_ENV for non-interactive, non-login shell",
);

Bash semantics worth mirroring

Per bash(1) (INVOCATION section):

  • For non-interactive non-login shells: if BASH_ENV is set in the environment, expand the value and source the resulting file (if it exists and is readable)
  • In POSIX/sh mode: same behavior using ENV instead of BASH_ENV
  • The value undergoes parameter expansion, command substitution, and arithmetic expansion before being used as a filename
  • Bash silently continues if the file does not exist (no error)
  • Behavior is suppressed when the effective UID/GID differ from the real ones (bash skips env-file reads in privileged contexts)

Environment

  • brush 0.4.0 (installed via Homebrew on macOS)
  • Darwin 25.4.0, arm64

Happy to take a stab at this — would follow up with a draft PR using the existing source_if_exists helper and the basic expansion path used elsewhere for shell variables.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: compatRelated to compatibility with standard shells

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions