shellhist-core
A from-scratch shell command-history reader — bash, zsh (EXTENDED_HISTORY), fish, and PowerShell PSReadLine into one uniform, timestamped HistoryEntry stream. No unsafe, no regex engine, no C bindings — reads a history file authored on any OS.
[]
= "0.1"
use ;
// Detect the format from the bytes (the filename only disambiguates ties)…
assert_eq!;
assert_eq!;
// …or just parse. zsh EXTENDED_HISTORY entries carry both timestamp and elapsed.
let entries = parse_auto;
assert_eq!;
assert_eq!;
assert_eq!;
What it parses
parse_auto(data, filename) sniffs the format and parses; detect(data, filename) returns the [Shell] without committing; parse(data, shell) parses a known format. Per-format entry points live in shellhist_core::{bash, zsh, fish, powershell}::parse. Every path yields the same [HistoryEntry] (shell, command, timestamp, elapsed, paths):
- bash (
.bash_history) — plain one-command-per-line, plus#<epoch>timestamp lines (HISTTIMEFORMAT) and multi-line commands that keep their embedded newlines. - zsh (
.zsh_history) — plain lines andEXTENDED_HISTORY: <start>:<elapsed>;<cmd>records with backslash continuation; bothtimestampandelapsedare retained. - fish (
fish_history) — the nearly-YAML- cmd:/when:/paths:record format with its 2-rule unescape; heuristically associated paths are kept on the entry. - PowerShell PSReadLine (
ConsoleHost_history.txt) — plain commands with backtick line continuation; no timestamps (the format records none).
A leading UTF-8 BOM is stripped (strip_bom); an undetectable file parses as plain one-command-per-line (Shell::Unknown).
Trust, but verify
#![forbid(unsafe_code)]; panic-free on crafted input (the workspace denies clippy::unwrap_used / expect_used in production code, parsing is lenient lossy-UTF-8 and bounds-checked); fuzzed with cargo-fuzz targets per format (bash, zsh, fish, powershell); the reader is exercised against a history file generated by a real bash subshell, not only synthetic fixtures.
Forensic analysis
Severity-graded anomaly auditing (history-clearing / timestamp-regression / download-pipe-to-shell / encoded-PowerShell findings) lives in the sibling shellhist-forensic crate, built on this one — the reader/analyzer split mirrors ntfs-core/ntfs-forensic.
Privacy Policy · Terms of Service · © 2026 Security Ronin Ltd