Can I create at tmux split which is a sub shell of the current pane? - tmux

The question is pretty self explanatory... I have a pane in tmux running bash, and I want to split it, but instead of running a fresh shell I want the new pane to be a sub shell of the first.

Here's a way using reptyr that has limitations which may not work for your case. You should expect to find this utility in a package for your system. I used the following script to test it out:
xterm -e 'tmux new-session -s mysession' &
sleep 1
tmux split-window -v -t 0
sleep 1
tmux send-keys -t 0 'cd /tmp;V=1' Enter
tmux send-keys -t 1 'cd /usr;V=3' Enter
sleep 1
tmux send-keys -t 0 'V=2 bash' Enter
sleep 1
tmux send-keys -t 0 'echo $$; echo $$ >/tmp/pid' Enter
sleep 1
tmux send-keys -t 1 'exec reptyr $(</tmp/pid)' Enter
sleep 2
tmux send-keys -t 1 'echo $(pwd) $$ V=$V' Enter
tmux send-keys -t 0 'echo $(pwd) $$ V=$V' Enter
We start by splitting a window running bash into two.
In the top pane (-t 0) we change the directory, and set an environment variable V to value 1, and in the bottom pane we change to a different directory and set V to 3, just to track what happens.
In the top pane we then start a child bash with V=2 in its environment, and echo the pid into a file.
In the bottom pane we run reptyr to attach to that pid, and then in both panes we see where we are.
The resulting output terminal looks like this:
$ cd /tmp;V=1
$ V=2 bash
$ echo $$; echo $$ >/tmp/pid
27236
$
[1]+ Stopped V=2 bash
$ echo $(pwd) $$ V=$V
/tmp 27184 V=1
$
----------------------------------------
$ cd /usr;V=3
$ exec reptyr $(</tmp/pid)
[-] Timed out waiting for child stop.
$ echo $(pwd) $$ V=$V
/tmp 27236 V=2
$
Clearly, the bottom pane is now process 27236 we launched in the top pane, with V=2 and the appropriate directory, so this has worked.

Related

TMUX: no space for new pane

Consider the TMUX
tmux new-session -d -s theSession
for p in {1..30}
do
echo "Welcome to Pane number #$p"
tmux split-window -v -p 140 -t theSession
tmux send-keys -t theSession "./run-exp-scr.sh" Enter
done
tmux attach -t theSession
When I run script I get :
no space for new pane
Any idea how to solve this ?
Googling your error I came across this mailing list link which seems to imply you need to tell tmux to relayout things with e.g. selectl tiled to ensure there's enough space. Add a select-layout call in your loop:
tmux split-window -v -p 140 -t theSession
tmux select-layout -t theSession tiled

Change tmux key-binding for bash script

We do have a bash script, which we can run on a cluster access node, that executes htop on all cluster child nodes, in order for us to monitor the whole cluster at once.
Now my question is, whether, there is a way to bind Ctrl-C or q for this script, without having to use the tmux prefix. The idea is, that this would make the script behave very similar to the regular htop command (which uses the q key binding to quit), and other users would not have to dive into the specifics of how to use tmux, when wanting to quit the window.
I am aware, that there is a way to change the behaviour using the .tmux.conf file. However, we do not want to set these keybinding globally, but only for this single script.
The command bash script looks like this:
tmux new -s logs_htop -d ssh-run htop 1
tmux select-pane -T 'cn01'
tmux splitw -v -p 50 -t logs_htop:0.0 ssh-run htop 5
tmux select-pane -T 'cn05'
tmux splitw -h -p 75 -t logs_htop:0.0 ssh-run htop 2
tmux select-pane -T 'cn02'
tmux splitw -h -p 66 -t logs_htop:0.1 ssh-run htop 3
tmux select-pane -T 'cn03'
tmux splitw -h -p 50 -t logs_htop:0.2 ssh-run htop 4
tmux select-pane -T 'cn04'
tmux splitw -h -p 75 -t logs_htop:0.4 ssh-run htop 6
tmux select-pane -T 'cn06'
tmux splitw -h -p 66 -t logs_htop:0.5 ssh-run htop 7
tmux select-pane -T 'cn07'
tmux splitw -h -p 50 -t logs_htop:0.6 "watch squeue -al"
tmux select-pane -T 'squeue'
tmux attach -t logs_htop
Yes, this is possible by connecting to a different tmux socket with a custom tmux config file.
First, create your custom tmux keybind in a separate conf file:
mkdir -p /etc/tmux
echo "bind-key -n C-c kill-session" > /etc/tmux/tmux-logs-htop.conf
# do not recommend q as htop is context-sensitive and q does not *always* mean quit
echo "bind-key -n q kill-session" >> /etc/tmux/tmux-logs-htop.conf
Next, create your custom tmux server:
tmux -L logs_htop -f /etc/tmux/tmux-logs-htop.conf
Lastly, edit your script to prefix every command with the particular socket / tmux server the commands are going to:
tmux -L logs_htop new -s logs_htop -d ssh-run htop 1
...
From man tmux:
-L socket-name
tmux stores the server socket in a directory under TMUX_TMPDIR or /tmp if it is unset.
The default socket is named default. This option allows a different socket name to be
specified, allowing several independent tmux servers to be run. Unlike -S a full path is
not necessary: the sockets are all created in the same directory.

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)

Tmux loading multiple enviroments from different files

Hello I would like to load multiple environments from different files. For example:
First File builds a session with 1 window and 3 panes.
Second File builds a session with 2 windows first window with 2 panes and second window with one pane.
Like:
tmux -f /path/to/file/basic.conf a
and then after detaching from the first session, i would like to load the same way the other enviroment.
tmux -f /path/to/file/scripting.conf a
but when i fire the second command i will attach to the first session (basic.conf).
But i would expect that when I fire the second script I would attach to the second session.
And tmux ls list only one session.
(The conf files by itself are running with no problem)
How is it possible to have multiple session build trough differnt conf files with tmux, and only with tmux no tmuxinator no tmuxp or anything else?
Or should i have one big conf file which builds everything that now is in muliply conf files?
basic.conf
SESSION_NAME="basic"
FIRST_WINDOW="shells"
SECOND_WINDOW="console"
source ~/.tmux.conf
new-session -s $SESSION_NAME -n $FIRST_WINDOW -d
split-window -h -t $SESSION_NAME
split-window -v -t $SESSION_NAME
new-window -n $SECOND_WINDOW -t $SESSION_NAME
select-window -t $SESSION_NAME:0.0
scripting.conf
SESSION_NAME="script"
FIRST_WINDOW="editor"
SECOND_WINDOW="console"
source ~/.tmux.conf
new-session -s $SESSION_NAME -n $FIRST_WINDOW -d
split-window -v -p 5 -t $SESSION_NAME
send-keys -t $SESSION_NAME:0.0 'cd ~/Code' C-m
send-keys -t $SESSION_NAME:0.0 'vim' C-m
send-keys -t $SESSION_NAME:0.1 'cd ~/Code' C-m
send-keys -t $SESSION_NAME:0.1 C-l C-m
new-window -n $SECOND_WINDOW -t $SESSION_NAME
send-keys -t $SESSION_NAME:1 'cd ~/Code' C-m
select-window -t $SESSION_NAME:0
I think I found a solution by myself.
The command:
tmux -f /path/to/file.conf a
should only be used when you would like to load another tmux config file instead of the default one.
If you like to start multiple sessions , which are preconfigured in files, then you have to do something like this:
tmux source-file -q .dotfiles/tmux/enviroments/basic.conf && tmux attach -t basic
Perhaps there is a better solution, but for now this solves my problem.
P.S. i made a little function to load the files less complicated.
function muxload(){
if [ -f ~/.dotfiles/tmux/enviroments/$1 ]; then
tmux source-file -q ~/.dotfiles/tmux/enviroments/$1 && tmux attach -t $1
fi
if [ -f ~/.dotfiles/tmux/enviroments/$1.conf ]; then
tmux source-file -q ~/.dotfiles/tmux/enviroments/$1.conf && tmux attach -t $1
fi
}
run it like this:
muxload {name_of_conf_file}

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