Skip to content

Instantly share code, notes, and snippets.

@beeftornado
Last active May 17, 2022 18:46
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save beeftornado/d98a9b9feed83b7ab2de to your computer and use it in GitHub Desktop.
Save beeftornado/d98a9b9feed83b7ab2de to your computer and use it in GitHub Desktop.
Save byobu (a tmux wrapper) sessions to a shell script that can be run to restore the session.
#!/usr/bin/env ruby
# Modified version of https://github.com/geebee/tmux-persistence to work with byobu
# and work on OSX.
require 'fileutils.rb'
# Start - Configuration Variables
sessionDir = ENV['HOME']+"/.byobu-sessions"
maxStoredSessions = 5
filesToRoll = 3
# End - Configuration Variables
FileUtils::makedirs(sessionDir) unless File.exists?(sessionDir)
files = []
Dir.entries(sessionDir).each do |e|
if e !~ /^\./
files << e
end
end
files.sort! unless files.length == 0
if files.length > maxStoredSessions
0.upto(filesToRoll - 1) do |index|
File.delete( sessionDir+ "/" + files[index] )
end
puts "Rotated stored sessions"
end
#%x[rm #{sessionDir}/*-restore]
sessions = %x[tmux list-sessions -F "\#{session_name}"].split("\n")
sessions.each do |sessionName|
rawPaneList = %x[tmux list-panes -t #{sessionName} -s -F "\#{window_index} \#{pane_index} \#{window_width} \#{window_height} \#{pane_width} \#{pane_height} \#{window_name} \#{pane_current_path} \#{pane_pid}"].split("\n")
panes = []
rawPaneList.each do |pane_line|
temp_pane = pane_line.split(" ")
panes.push({
windowIndex: Integer(temp_pane[0]),
paneIndex: Integer(temp_pane[1]),
windowWidth: Integer(temp_pane[2]),
windowHeight: Integer(temp_pane[3]),
paneWidth: Integer(temp_pane[4]),
paneHeight: Integer(temp_pane[5]),
window_name: temp_pane[6],
cwd: temp_pane[7],
pid: temp_pane[8]
})
end
sessionScript = ""
panes.each_index do |idx|
pane = panes[idx]
pane[:cmd] = %x[ps -o command -p #{pane[:pid]} | awk 'NR>1'].delete("\n")
pane[:cmd] = %x[ps -o command #{pane[:pid]} | awk 'NR>1'].delete("\n").gsub(/^-/,"") unless pane[:cmd] != ""
sessionScript += " # Restore (forcibly) window '#{pane[:window_name]}' to position #{pane[:windowIndex]}\n"
sessionScript += " $BYOBU new-window -t $SESSION:#{pane[:windowIndex]} -k -n #{pane[:window_name]}\n"
sessionScript += " $BYOBU send-keys -t $SESSION:#{pane[:windowIndex]} 'cd \"#{pane[:cwd]}\" && clear' C-m\n\n"
if pane[:paneIndex] > 0
if pane[:paneWidth] < pane[:windowWidth]
sessionScript += " $BYOBU join-pane -h -l #{pane[:paneWidth]} -s $SESSION:#{pane[:windowIndex] +1}.0 -t $SESSION:#{pane[:windowIndex]}\n\n"
else
sessionScript += " $BYOBU join-pane -v -l #{pane[:paneHeight]} -s $SESSION:#{pane[:windowIndex] +1}.0 -t $SESSION:#{pane[:windowIndex]}\n\n"
end
end
end
restore_file = sessionDir + "/" + sessionName + "-restore"
File.open(restore_file, "w") {
|f| f.write(%Q[#!/usr/bin/env bash
SESSION=#{sessionName}
BYOBU=\\byobu # bypass any aliasing
if [ -z $TMUX ]; then
# if session already exists, attach
$BYOBU has-session -t $SESSION 2>/dev/null
if [ $? -eq 0 ]; then
echo \"Session $SESSION already exists. Attaching...\"
$BYOBU attach -t $SESSION
exit 0;
fi
# assumption by this point is user hasn't already started tmux/byobu, since we lazily quit if there was one
# (could be done, but this isn't my job...and I need to get to my job).
# Refactored to work even if user has some default session creation already configured in their ~/.byobu/.tmux.conf
$BYOBU start-server
#{sessionScript}
# attach to new session
$BYOBU select-window -t $SESSION:#{panes[0][:windowIndex]}
$BYOBU attach-session -t $SESSION
fi
])
# make script executable
f.chmod( 0744 )
}
end
@Uiuran
Copy link

Uiuran commented Nov 28, 2014

Hi, i got that error:

is there something wrong or iam misusing the script ? thank you

│./byobusave.rb:42: odd number list for Hash
│windowIndex: Integer(temp_pane[0]),
│ ^
│./byobusave.rb:42: syntax error, unexpected ':', expecting '}'
│windowIndex: Integer(temp_pane[0]),
│ ^
│./byobusave.rb:42: syntax error, unexpected ',', expecting kEND
│./byobusave.rb:43: syntax error, unexpected ',', expecting kEND
│./byobusave.rb:44: syntax error, unexpected ',', expecting kEND
│./byobusave.rb:45: syntax error, unexpected ',', expecting kEND
│./byobusave.rb:46: syntax error, unexpected ',', expecting kEND
│./byobusave.rb:47: syntax error, unexpected ',', expecting kEND
│./byobusave.rb:49: syntax error, unexpected ':', expecting '='
│cwd: temp_pane[7],
│ ^
│./byobusave.rb:50: syntax error, unexpected ':', expecting '='
│pid: temp_pane[8]
│ ^
│./byobusave.rb:51: syntax error, unexpected '}', expecting kEND
│./byobusave.rb:97: syntax error, unexpected $end, expecting kEND

@zotherstupidguy
Copy link

how to restore?

@leoetlino
Copy link

Simply run the restore script located in ~/.byobu-sessions/.

@SanojR
Copy link

SanojR commented Feb 16, 2016

I know that it is possible to save the scrollback of the session with tmux capture-pane. Unfortunately, I dont really understand the ruby code. Is it feasible to include the scrollback in the saved session?

@falzard
Copy link

falzard commented Mar 24, 2017

This doesn't work.

So I looked at the bash code. I'm not good at bash, I know nothing about ruby but I made it work (hackfix I guess).

I only added this line:
$BYOBU new -s $SESSION

After:
$BYOBU start-server

Although it annoyed me to install ruby-full only for that small script but well, it seems like it works!

EDIT: if you close one window, and you rerun the script, it won't restore that closed window.
EDIT 2: if you kill the byobu server, if you delete all sessions, and if you restore using the script, it won't reload any history, just the names and number of windows :'(
EDIT 3: ok it's too buggy lol, I can't make it work
EDIT 4: maybe guys should try tmux-resurrect instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment