running my tmux panes automatically - tmux

Inspiring from this blog post I tried to run my project on 20 tmux panes with different inputs at once as below.
~/foo/tmux_project_session.sh file consists the following:
#!/usr/bin/tmux source-file
new-session -d
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
split-window -d -t 0 -v
prefix="cd ~/foo/ && source virtualenv/bin/activate && python project.py"
suffix="-p parameter"
send-keys -t 0 "${prefix} variable_1 ${suffix}" enter
send-keys -t 1 "${prefix} variable_2 ${suffix}" enter
send-keys -t 2 "${prefix} variable_3 ${suffix}" enter
send-keys -t 3 "${prefix} variable_4 ${suffix}" enter
send-keys -t 4 "${prefix} variable_5 ${suffix}" enter
send-keys -t 5 "${prefix} variable_6 ${suffix}" enter
send-keys -t 6 "${prefix} variable_7 ${suffix}" enter
send-keys -t 7 "${prefix} variable_8 ${suffix}" enter
send-keys -t 8 "${prefix} variable_9 ${suffix}" enter
send-keys -t 9 "${prefix} variable_10 ${suffix}" enter
send-keys -t 10 "${$prefix} variable_11 ${suffix}" enter
send-keys -t 11 "${$prefix} variable_12 ${suffix}" enter
send-keys -t 12 "${$prefix} variable_13 ${suffix}" enter
send-keys -t 13 "${$prefix} variable_14 ${suffix}" enter
send-keys -t 14 "${$prefix} variable_15 ${suffix}" enter
send-keys -t 15 "${$prefix} variable_16 ${suffix}" enter
send-keys -t 16 "${$prefix} variable_17 ${suffix}" enter
send-keys -t 17 "${$prefix} variable_18 ${suffix}" enter
send-keys -t 18 "${$prefix} variable_19 ${suffix}" enter
send-keys -t 19 "${$prefix} variable_20 ${suffix}" enter
select-pane -t 3
attach
I run this code as an argument as below:
tmux -CC source-file ~/foo/tmux_project_session.sh
It runs tmux -CC and create 4 vertical panes. Runs as it should be on the 2nd, 3rd and 4th panes. It does not do anything on the 1st pane.
Could you please advise me on what would be my error on my script?
What prevent 1st pane to work with variable_1 and why wouldn't the rest of panes even start?
Thanks

Related

How to create tmux window without attaching to the session?

I'd like to be able to create a new tmux window(tab) in a session called 'scratch' running a custom command (ie. 'ping www.google.com') without attaching to the session. I'd also like 'scratch' to be created if it doesn't exist.
How would the shell script be written?
Plagiarized and altered a bit from another of my answers, here's an example:
TMUX_SESSION_NAME='scratch'
tmux new-session -d -s $TMUX_SESSION_NAME >/dev/null
tmux new-window -t $TMUX_SESSION_NAME
tmux send-keys -t $TMUX_SESSION_NAME:1.0 'ping www.google.com' Enter
More info (my configuration):
Here's what I use to start my tmux sessions. The argument to the function would be the name of the session you want to create.
If this does not answer your question, please comment and edit your question to that it is more clear to me.
tmuxstart() {
tmux new-session -d -s $1 >/dev/null
tmux rename-window -t $1:0 'main'
tmux splitw -v -p 10 -t $1:0.0
tmux splitw -h -p 80 -t $1:0.1
#required; otherwise pane numbering is bs
tmux select-pane -t $1:0.0
tmux splitw -h -p 5 -t $1:0.0
tmux send-keys -t $1:0.2 'sudo htop' Enter
tmux send-keys -t $1:0.1 'tmux clock -t $1:0.1' Enter
tmux select-pane -t $1:0.0
tmux new-window -t $1
tmux rename-window -t $1:1 'second'
tmux splitw -v -p 10 -t $1:1.0
tmux splitw -h -p 80 -t $1:1.1
tmux select-pane -t $1:1.0
tmux splitw -h -p 5 -t $1:1.0
tmux clock -t $1:1.1
tmux new-window -t $1
tmux rename-window -t $1:2 'scratch'
tmux splitw -v -p 10 -t $1:2.0
tmux select-pane -t $1:2.0
tmux splitw -h -p 5 -t $1:2.0
tmux clock -t $1:2.1
tmux select-window -t $1:0.0
tmux a -t $1
}

tmux can't find session: Editor

I'm trying to write a script that sets up a series of tmux panes within one window. Each pane wil have a separate program loaded into it, mimicking an IDE.
This is the script I'm running:
#!/bin/sh
tmux new-session -s Editor -n Desktop -d
# Set up main editor window
tmux select-window -t Editor:Desktop
tmux -u attach -t Editor
# Create splits
tmux send-keys -t Editor:Desktop 'C-b %' # 0
tmux send-keys -t Editor:Desktop 'C-b "' # 1
tmux send-keys -t Editor:Desktop 'C-b "' # 2
tmux send-keys -t Editor:Desktop 'C-b "' # 3
# Load programs into panes
tmux select-pane -t 0
tmux send-keys -t Editor:Desktop 'ccb' Enter
tmux send-keys -t Editor:Desktop 'vim' Enter
tmux select-pane -t 1
tmux send-keys -t Editor:Desktop 'ccb' Enter
tmux send-keys -t Editor:Desktop 'working_set --watch .' Enter
tmux select-pane -t 2
tmux send-keys -t Editor:Desktop 'ccb' Enter
tmux send-keys -t Editor:Desktop 'clear' Enter
tmux select-pane -t 3
tmux send-keys -t Editor:Desktop 'ccb' Enter
tmux send-keys -t Editor:Desktop 'npm start' Enter
This doesn't do as expected. Instead, it loads up a window without panes. When I exit, I see the errors:
can't find session: Editor
can't find session: Editor
can't find session: Editor
can't find session: Editor
can't find session: Editor
can't find session: Editor
can't find session: Editor
can't find session: Editor
can't find session: Editor
can't find session: Editor
can't find session: Editor
can't find pane: 3
can't find session: Editor
can't find session: Editor
You should use tmux split-window to achieve what you want. Keys sent by send-keys are interpreted as input in command line, not shortcut to operate tmux.
#!/bin/sh
# Note: the default window, pane index start from 0
# you may need to modify the following index if you changed it in .tmux.conf
# E.g.
# set -g base-index 1 # start window index at 1
# setw -g pane-base-index 1 # pane index starts at 1
tmux has-session -t development
if [ $? != 0 ]; then
tmux new-session -s Editor -n Desktop -d
# Set up main editor window
tmux select-window -t Editor:Desktop
# Create splits (must executed outside of the session)
tmux split-window -h -t Editor
tmux split-window -v -t Editor
tmux split-window -v -t Editor
tmux split-window -v -t Editor
# Load programs into panes
tmux select-pane -t 0
tmux send-keys -t Editor:Desktop 'ccb' Enter
tmux send-keys -t Editor:Desktop 'vim' Enter
tmux select-pane -t 1
tmux send-keys -t Editor:Desktop 'ccb' Enter
tmux send-keys -t Editor:Desktop 'working_set --watch .' Enter
tmux select-pane -t 2
tmux send-keys -t Editor:Desktop 'ccb' Enter
tmux send-keys -t Editor:Desktop 'clear' Enter
tmux select-pane -t 3
tmux send-keys -t Editor:Desktop 'ccb' Enter
tmux send-keys -t Editor:Desktop 'npm start' Enter
fi
tmux attach -t Editor
References
tmux 2: Productive Mouse-Free Development, a comprehensive tutorial about tmux. (maybe a little outdated)

How to write a tmux script so that it automatically split windows and opens a set of files?

I am new to Tmux. I know that you can write script to automate Tmux, in case your computer shuts down. I can write the following:
#!/bin/bash
tmux new-session -d -s MY_SESSION_NAME
tmux split-window -h
vim <path to file1>
This only opens up a 1 single vim editor page for file1, not in tmux, and not in any tmux split. Is it possible automate the file opening like this?
Here's an example of the automation I have on my tmux session.
Target a specific session/pane/window with <name>:<window>.<pane>, where window and panes are numbered, starting with 0.
Send-keys is the way to send a command to a particular tmux pane/window. the -d causes tmux to start in detached mode so you can keep sending more commands to it before actually attaching.
tmuxstart() {
tmux new-session -d -s sess >/dev/null
tmux rename-window -t sess:0 'main'
tmux splitw -v -p 10 -t sess:0.0
tmux splitw -h -p 80 -t sess:0.1
#required; otherwise pane numbering is bs
tmux select-pane -t sess:0.0
tmux splitw -h -p 5 -t sess:0.0
tmux send-keys -t sess:0.2 'sudo htop' Enter
tmux send-keys -t sess:0.1 'tmux clock -t sess:0.1' Enter
tmux select-pane -t sess:0.0
tmux new-window -t sess
tmux rename-window -t sess:1 'second'
tmux splitw -v -p 10 -t sess:1.0
tmux splitw -h -p 80 -t sess:1.1
tmux select-pane -t sess:1.0
tmux splitw -h -p 5 -t sess:1.0
tmux clock -t sess:1.1
tmux new-window -t sess
tmux rename-window -t sess:2 'scratch'
tmux splitw -v -p 10 -t sess:2.0
tmux select-pane -t sess:2.0
tmux splitw -h -p 5 -t sess:2.0
tmux clock -t sess:2.1
tmux select-window -t sess:0.0
tmux a -t sess
}

tmux 8-pane "sane" tiled layout

When I use tmux with 8 panes it tiles them like this:
But I want them tiled like this:
Any way to accomplish this automatically?
Try the below bash script:
tmux new -s test -d
tmux selectp -t 0 # select the first (0) pane
tmux splitw -h -p 75 # split it into two horizontal parts
tmux selectp -t 0 # select the first (0) pane
tmux splitw -v -p 50 # split it into two vertical halves
# After this 3 panes will be created with pane number 0 (left- horizontal)
# Pane 1 (vertical pane under the pane 0)
# And Pane 2 with the remaining screen size
# Then we divide this remaining pane 2 into three similar panes
# repeat this till all 8 panes are created
tmux selectp -t 2 # select the new, second (2) pane
tmux splitw -h -p 66 # split it into two halves
tmux selectp -t 2 # select the second (2) pane
tmux splitw -v -p 50 # split it into two vertical halves
tmux selectp -t 4 # select the new, fourth (4) pane
tmux splitw -h -p 50 # split it into two halves
tmux selectp -t 4 # select the fourth (4) pane
tmux splitw -v -p 50 # split it into two halves
tmux selectp -t 6 # select the new, sixth (6) pane
tmux splitw -v -p 50 # split it into two halves
tmux selectp -t 0 # go back to the first pane
tmux attach -t test
The trick is to identify the pane number and split it accordingly.
Add the following lines to the above script and you can see the pane number and how it is arranged by the tmux.
tmux send-keys -t 0 'echo "-- Pane 1 ---"' Enter
tmux send-keys -t 1 'echo "-- Pane 2 ---"' Enter
tmux send-keys -t 2 'echo "-- Pane 3 ---"' Enter
tmux send-keys -t 3 'echo "-- Pane 4 ---"' Enter
tmux send-keys -t 4 'echo "-- Pane 5 ---"' Enter
tmux send-keys -t 5 'echo "-- Pane 6 ---"' Enter
tmux send-keys -t 6 'echo "-- Pane 7 ---"' Enter
tmux send-keys -t 7 'echo "-- Pane 8 ---"' Enter
send-keys will send the command echo "-- pane number --" to the panes specified by -t option.
You can make the panes yourself with the tmux command line:
tmux splitw -v -p 20 -t ssh_tmux:0.0 #splits window0, pane0 vertically
tmux splitw -h -p 80 -t ssh_tmux:0.1 #splits the lower pane horizontally
You'd have to play with -p which sets the relative widths of the panes, but you could write a bash script to to this with a single command.
TL;DR: I don't think there's an easy way, but it's not impossible.
The following bash script works for me:
tmux new -s logs -d
tmux splitw -v -p 50 -t logs:0.0
tmux splitw -h -p 75 -t logs:0.0
tmux splitw -h -p 66 -t logs:0.1
tmux splitw -h -p 50 -t logs:0.2
tmux splitw -h -p 75 -t logs:0.4
tmux splitw -h -p 66 -t logs:0.5
tmux splitw -h -p 50 -t logs:0.6
tmux attach -t logs

How to create a layout and run commands in at tmux launch?

I am trying to write a script I can run/source so tmux set a specific layout and run commands. I have some results.
Here is what I've written so far:
selectp -t 1
splitw -v -p 15
splitw -h -p 50
selectp -t 1
send-keys 'cd ~/code/octoly' Enter
send-keys 'vim .' Enter
selectp -t 2
send-keys 'cd ~/code/octoly' Enter
send-keys 'drails c' Enter
new-window -d -n server -c ~/code/octoly
selectw -t 2
send-keys 'fd' Enter
splitw -h -p 50
send-keys 'cd ~/code/octoly' Enter
send-keys 'drails s' Enter
selectp -t 1
splitw -v -p 50
send-keys 'cd ~/code/octoly' Enter
send-keys 'be guard' Enter
What works more or less is the creation of the second window and the panes. Though the panes does not give me what I want. They are all created in the first window, none are created in the second.
Here is what I run to start tmux:
tmux new 'tmux move-window -t 99 \; source-file ~/.tmux/session_octoly'
Furthermore, where I'm really lost is that if I run each command by hand one by one, it gives me what I want.
What am I missing here?
First of all, you're using the -d flag in new-window that does not make the new window the current window:
If -d is given, the session does not make the new window the current window.
However I would probably spin up tmux in a different way, using tmux -f flag to use an ad-hoc config file that does what you want.
Please check the commands before running it in you're environment.
# File: ~/.tmux/octoly.conf
# Load default .tmux.conf
source-file ~/.tmux.conf
# setup octoly session
new-session -s octoly -n editor -d -c ~/code/octoly
send-keys 'vim .' Enter
split-window -v -p 15 -c ~/code/octoly
send-keys 'drails c' Enter
split-window -h -p 50 -c ~/code/octoly
# Select vim pane
select-pane -t 1
# create second window
new-window -n server -c ~/code/octoly
send-keys 'fd' Enter
split-window -h -p 50 -c ~/code/octoly
send-keys 'drails s' Enter
select-pane -t 1
split-window -v -p 50 -c ~/code/octoly
send-keys 'be guard' Enter
# Optional step, reselect window 1 (the one with vim)
select-window -t editor
Then you need to launch tmux using:
tmux -f ~/.tmux/octoly.conf attach
Another alternative would be to build a bash script sending the same commands.
Note: I've used the -c flag to specify the start directory instead of running every time a cd command. Given that every command is run in the same folder you can take them out in the split-window commands.

Resources