Bash Piped Logging
Luke Hebert
- 2 minutes read - 338 wordsNeed a lightweight way to log everything a bash session prints without installing a full logging framework? A named pipe (FIFO) paired with tee does the job in five lines. The setup below redirects both stdout and stderr through a pipe into a background tee process, so you still see output on your terminal while a copy lands in a log file.
The Setup
logfile=mylogfile
mkfifo ${logfile}.pipe
tee < ${logfile}.pipe $logfile &
exec &> ${logfile}.pipe
rm ${logfile}.pipeWhat Each Line Does
logfile=mylogfile- Sets the base name for the log file. Change it to whatever fits your workflow.mkfifo ${logfile}.pipe- Creates a named pipe (FIFO) that acts as the conduit between your shell and theteeprocess.tee < ${logfile}.pipe $logfile &- Startsteein the background. It reads from the pipe and writes to both the terminal and the log file simultaneously.exec &> ${logfile}.pipe- Redirects all subsequent stdout and stderr from the current shell into the pipe. From this point on, everything you print goes throughtee.rm ${logfile}.pipe- Cleans up the FIFO file. The pipe still works becauseteeholds an open file descriptor to it.
Stopping the Logger
To stop logging, kill the background tee process:
kill %1Or, if you lost the job number:
pkill -f "tee.*${logfile}.pipe"After that, your shell’s stdout and stderr revert to the terminal.
A Few Things to Keep in Mind
The exec &> redirection is session-scoped. It does not propagate to child processes unless they inherit the file descriptors, which they do by default. If you need per-command logging instead, wrap individual commands with tee directly.
If the tee process dies, writes to the pipe will block or fail silently. Make sure the log file’s directory is writable and that you have not hit a disk quota before starting a long-running session.
This pattern is handy for ad-hoc debugging, capturing output from interactive tools, or building a quick audit trail without reaching for script or a full logging daemon.