Skip to content

Instantly share code, notes, and snippets.

@lmmx
Last active May 30, 2025 16:52
Show Gist options
  • Save lmmx/5f948cca8a18dc5d646a7171d7daa467 to your computer and use it in GitHub Desktop.
Save lmmx/5f948cca8a18dc5d646a7171d7daa467 to your computer and use it in GitHub Desktop.
batcmd: Separate stdout and stderr with syntax highlighting

batcmd - Separate stdout and stderr with syntax highlighting

A bashrc shell function that runs any command and displays stdout and stderr as separate streams with bat syntax highlighting. Uses file descriptor swapping to cleanly separate the streams without temporary files or running the command twice.

Features:

  • Configurable syntax highlighting language
  • Clean separation with "STDOUT" and "STDERR" headers
  • Works with any command
  • No temporary files or command duplication

Example: batstreams cargo run

  • Note that piped usage will work but stderr isn't captured, obviously (can still useful to see the STDOUT separately and with highlighting). If you need the STDERR too then use it before the command not after with a pipe
batcmd() {
local language="${BATCMD_LANGUAGE:-rust}"
# Parse options
while [[ $# -gt 0 ]]; do
case $1 in
-l|--language)
language="$2"
shift 2
;;
*)
break
;;
esac
done
# Check if being used as a pipe
if [[ ! -t 0 ]]; then
# Reading from stdin (pipe mode)
bat -l"$language" --file-name="STDIN"
return
fi
# Original command execution mode
local stdout_file=$(mktemp)
local stderr_file=$(mktemp)
"$@" >"$stdout_file" 2>"$stderr_file"
local exit_code=$?
# Show stdout if not empty
if [[ -s "$stdout_file" ]]; then
bat -l"$language" --file-name="STDOUT" "$stdout_file"
fi
# Show stderr if not empty
if [[ -s "$stderr_file" ]]; then
bat -l"$language" --file-name="STDERR" "$stderr_file"
fi
# Cleanup
rm "$stdout_file" "$stderr_file"
return $exit_code
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment