tmux log-file silent failure when deployment script lacks write permission
0 reputation · 21 Mar 2023, 08:47 UTC
0 reputation · 21 Mar 2023, 08:47 UTC
Capture the complete output of a deployment script running inside a tmux pane so that a later post‑mortem can correlate the exact error messages and exit status.
The log-file option (global or per‑window) appends raw pane output—including ANSI escape sequences—without timestamps or rotation. Logging begins only for panes created after the option is set; existing panes are unaffected. If the target log file cannot be written due to permission problems, tmux fails silently and no output is recorded, leaving no indication that logging stopped.
Your diagnosis is correct: when the log-file path is not writable by the tmux server process, tmux does not surface an error — logging simply never starts, and you find out after the deployment. There is no built-in fix for that silence, so the reliable pattern is: verify the file is actually growing before launching the deployment, post-process the raw log to strip ANSI sequences, and handle rotation yourself because tmux has none.
Checking the option value alone is not enough — tmux show-options -g log-file only proves the path is configured, not that tmux can open it. Do a three-step check:
tmux show-options -g log-file (or show-window-options if set per window).ls -l /path/to/deploy.log and check the owner matches the user running the tmux server. A quick functional test is to create a new pane — remember, only panes created after the option is set are logged — run echo tmux-log-test in it, then tail -n 5 /path/to/deploy.log. If the test line appears, the file is open and appending.The functional test in step 2 is the key part: it converts the silent-failure mode into an observable one. If the file does not grow, fix permissions (chmod/chown on the directory, not just the file, since tmux may need to create it) and retest.
tmux records the raw byte stream the application emits, so colors, cursor movement, and redraw sequences are all in the file. tmux offers no plain-text mode, so post-process. Two common approaches:
# Option A: sed with an escape-sequence filter
sed -e 's/\x1b\[[0-9;]*[a-zA-Z]//g' -e 's/\x1b[][()][0-9;]*//g' deploy.log > deploy.clean.log
# Option B: col, which also resolves carriage returns / line overwrites
col -b < deploy.log > deploy.clean.logcol -b is often the better choice for deployment logs because tools with progress bars rewrite lines using carriage returns, and col collapses those into the final rendered text. Keep the raw file too — the escape sequences can occasionally matter when reconstructing exactly what an operator saw.
There is no built-in mechanism. log-file appends indefinitely, and tmux will not rotate, truncate, or warn. The common patterns are:
logrotate entry with copytruncate (tmux holds the file descriptor open, so plain move-and-recreate rotation leaves tmux writing to the old inode).log-file, use pipe-pane -o 'cat >> /path/deploy.log' routed through a tool that enforces size limits. Be aware pipe-pane depends on the external process staying alive and can introduce buffering delays, so it trades the silent-permission failure mode for a process-liveness failure mode.set -g log-file "$HOME/logs/deploy-$(date +%Y%m%d-%H%M%S).log") plus a periodic cleanup of files older than your retention window. This sidesteps rotation entirely.This assumes a reasonably recent tmux (3.x) on Linux; option names and pipe-pane behavior are stable across 2.x–3.x, but verify against your installed tmux -V and man page. The exact sed regex may need adjustment for unusual sequences, which is another reason to prefer col -b where available. If your post-mortem also needs the exit status, log it explicitly — e.g., end the deployment command with ; echo "EXIT=$?" — since the pane log captures output, not process metadata.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.