Created out of the lack of a standardised method to check how a shell is configured & what files are affecting the running shell process.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-06-07 10:58:21 +01:00
assets Initial public release 2026-06-07 10:58:21 +01:00
docs/agents Initial public release 2026-06-07 10:58:21 +01:00
man Initial public release 2026-06-07 10:58:21 +01:00
samples Initial public release 2026-06-07 10:58:21 +01:00
src Initial public release 2026-06-07 10:58:21 +01:00
tests Initial public release 2026-06-07 10:58:21 +01:00
.gitignore Initial public release 2026-06-07 10:58:21 +01:00
AGENTS.md Initial public release 2026-06-07 10:58:21 +01:00
Cargo.lock Initial public release 2026-06-07 10:58:21 +01:00
Cargo.toml Initial public release 2026-06-07 10:58:21 +01:00
LICENSE Initial public release 2026-06-07 10:58:21 +01:00
LICENSE-APACHE Initial public release 2026-06-07 10:58:21 +01:00
LICENSE-MIT Initial public release 2026-06-07 10:58:21 +01:00
README.md Initial public release 2026-06-07 10:58:21 +01:00

shellwhy terminal icon with a question mark

shellwhy

Explain which shell startup files are controlling a shell session.

Rust 2024 License: MIT OR Apache-2.0 Status: MVP AI assisted

shellwhy answers a practical dotfiles question: "why is my shell doing this?"

It inspects the current or requested shell mode, applies startup-file rules, safely parses obvious source statements, detects common shell tooling hooks, and reports what is inferred, possible, missing, skipped, or observed by trace mode.

Features

  • Static startup-file rules for bash, zsh, and fish.
  • Conservative fallback rules for sh/dash, ksh/mksh, tcsh/csh, and nu.
  • Safe static parsing for obvious source file and . file statements.
  • Detection for common shell tooling hooks, including starship, oh-my-zsh, zinit, direnv, asdf, pyenv, nvm, fnm, fisher, and tide.
  • Human-readable, plain, and JSON output.
  • Linux trace mode using strace when available.

Install

From a checkout:

cargo install --path .

Or build a local release binary:

cargo build --release
./target/release/shellwhy --help

Usage

Inspect the current environment and infer the current shell:

shellwhy

Explain bash startup files for the current user:

shellwhy --shell bash

Explain zsh in a specific mode:

shellwhy --shell zsh --login --interactive

Print machine-readable output:

shellwhy --shell bash --json
shellwhy --shell fish --plain

Run Linux syscall tracing with strace and merge observed files:

shellwhy trace --shell fish
shellwhy trace --shell zsh --login --interactive

Explain why shell-startup certainty is hard:

shellwhy explain

Confidence Labels

shellwhy avoids pretending that static analysis can prove runtime shell behavior.

Label Meaning
confirmed Observed by trace mode.
inferred Follows from shell rules or a safely parsed source statement.
possible Exists or is installed, but static mode cannot prove it loads.
missing Expected or possible path does not exist.
skipped Not loaded because mode or precedence rules exclude it.
unknown There is not enough information.

Static Mode

Static mode does not execute shell code. It can:

  • Identify the target shell from --shell, $SHELL, or parent process metadata.
  • Infer login, interactive, SSH, and terminal context from flags, process argv, TTY state, and environment.
  • Apply startup rules for the selected shell and mode.
  • Check whether startup files exist.
  • Show files skipped because another file takes precedence, such as bash reading only the first existing ~/.bash_profile, ~/.bash_login, or ~/.profile.
  • Parse simple source statements without evaluating arbitrary shell code.

Static mode cannot prove conditional branches, dynamic paths, plugin-manager side effects, aliases, functions, exports, or PATH changes created at runtime.

Trace Mode

Trace mode launches a fresh target shell and observes file access through a platform backend.

Current backend:

  • Linux: strace

Planned backend:

  • macOS: dtruss or fs_usage

Trace mode may run user startup code because it starts the requested shell. Use static mode when you need non-invasive analysis.

Project Layout

src/detector.rs       Shell detection and mode inference
src/rules/            Shell-specific startup rules
src/scanner.rs        Filesystem checks and source expansion
src/source_parser.rs  Safe parser for simple source statements
src/trace.rs          Platform trace backend
src/reporter.rs       Report assembly
src/formatter.rs      Pretty, plain, and JSON output

Sample output files are in samples/.

Development

Run the test suite:

cargo test

Check formatting:

cargo fmt --check

Run Clippy:

cargo clippy --all-targets --all-features -- -D warnings

AI Use Citation

This repository was developed with AI assistance from OpenAI Codex. OpenAI describes Codex as a coding agent for building and shipping software with AI: https://openai.com/codex/.

AI-generated suggestions were reviewed by the maintainer before being accepted.

License

Licensed under either of: