|
| 1 | +#!/bin/bash |
| 2 | +# |
| 3 | +# By Victor Orlikowski. Public domain. |
| 4 | +# |
| 5 | +# This script maintains snapshots of each pane's |
| 6 | +# history buffer, for each tmux session you are running. |
| 7 | +# |
| 8 | +# It is intended to be run by cron, on whatever interval works |
| 9 | +# for you. |
| 10 | + |
| 11 | +# Maximum number of snapshots to keep. |
| 12 | +max_backups=12 |
| 13 | +# Names of sessions you may wish to exclude from snapshotting, |
| 14 | +# space separated. |
| 15 | +ignore_sessions="" |
| 16 | +# The directory into which you want your snapshots placed. |
| 17 | +# The default is probably "good enough." |
| 18 | +backup_dir=~/.tmux_backup/snapshot |
| 19 | + |
| 20 | +######################################################################## |
| 21 | + |
| 22 | +# Rotate previous backups. |
| 23 | +i=${max_backups} |
| 24 | +while [[ ${i} != 0 ]] ; do |
| 25 | +if [ -d ${backup_dir}.${i} ] ; then |
| 26 | + if [[ ${i} = ${max_backups} ]] ; then |
| 27 | + rm -r ${backup_dir}.${i} |
| 28 | + else |
| 29 | + mv ${backup_dir}.${i} ${backup_dir}.$((${i}+1)) |
| 30 | + fi |
| 31 | +fi |
| 32 | +i=$((${i}-1)) |
| 33 | +done |
| 34 | + |
| 35 | +if [ -d ${backup_dir} ] ; then |
| 36 | + mv ${backup_dir} ${backup_dir}.1 |
| 37 | +fi |
| 38 | + |
| 39 | +## Dump hardcopy from all windows in all available tmux sessions. |
| 40 | +unset TMUX |
| 41 | +for session in $(tmux list-sessions | cut -d' ' -f1 | sed -e 's/:$//') ; do |
| 42 | + for ignore_session in ${ignore_sessions} ; do |
| 43 | + if [ ${session} = ${ignore_session} ] ; then |
| 44 | + continue 2 |
| 45 | + fi |
| 46 | + done |
| 47 | + |
| 48 | + # Session name can contain the colon character (":"). |
| 49 | + # This can screw up addressing of windows within tmux, since |
| 50 | + # target windows are specified as target-session:target-window. |
| 51 | + # |
| 52 | + # We use uuidgen to create a "safe" temporary session name, |
| 53 | + # which we then use to create a "detached" session that "links" |
| 54 | + # to the "real" session that we want to back up. |
| 55 | + tmpsession=$(uuidgen) |
| 56 | + tmux new-session -d -s "$tmpsession" -t "$session" |
| 57 | + HISTSIZE=$(tmux show-options -g -t "$tmpsession" | grep "history-limit" | awk '{print $2}') |
| 58 | + for win in $(tmux list-windows -t "$tmpsession" | grep -v "^\s" | cut -d' ' -f1 | sed -e 's/:$//'); do |
| 59 | + session_dir=$(echo "$session" | sed -e 's/ /_/g' | sed -e 's%/%|%g') |
| 60 | + win_spec="$tmpsession":"$win" |
| 61 | + |
| 62 | + if [ ! -d ${backup_dir}/${session_dir}/${win} ] ; then |
| 63 | + mkdir -p ${backup_dir}/${session_dir}/${win} |
| 64 | + fi |
| 65 | + |
| 66 | + for pane in $(tmux list-panes -t "$win_spec" | cut -d' ' -f1 | sed -e 's/:$//'); do |
| 67 | + pane_path=${backup_dir}/${session_dir}/${win}/${pane} |
| 68 | + pane_spec="$win_spec"."$pane" |
| 69 | + |
| 70 | + tmux capture-pane -t "$pane_spec" -S -${HISTSIZE} |
| 71 | + tmux save-buffer ${pane_path} |
| 72 | + |
| 73 | + if [ ! -s ${pane_path} ] ; then |
| 74 | + sleep 1 |
| 75 | + rm ${pane_path} |
| 76 | + fi |
| 77 | + done |
| 78 | + done |
| 79 | + tmux kill-session -t "$tmpsession" |
| 80 | + |
| 81 | +done |
0 commit comments