Tmux not detaching, sending keys from script - tmux

I have a remote server that I can reboot remotely, and I'm trying to make a script that starts my RESTful service. The script is called from .bash_profile. It starts it correctly, but it stays attached to the new tmux session, and hangs until I ssh in and manually detach it. Currently I'm sending C-b d but it doesn't detach.
Here is my small script:
tmux new-session -s cf
tmux send-keys -t cf 'cd ~/server' C-m
tmux send-keys -t cf 'sudo ./gradlew jettyRun' C-m
tmux send-keys -t cf 'C-b d'
How can I achieve this?

you can detach the session when creating it using -d :
tmux new-session -ds cf
and then you can access it anyway

Related

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.

How do i switch the active tmux session inside a shell script

I am trying to create an automated clean shutdown of my opensimulator servers.
On each server, I have several Tmux sessions. Inside each session, there are several windows. In the following example, there are only two sessions to keep things simple.
sara#opensim:~$ tmux ls
Robust: 5 windows (created Tue May 12 22:08:28 2020)
Simulators01: 6 windows (created Tue May 12 23:30:38 2020)
sara#opensim:~$
In the full version, there will be 10+ Simulator sessions.
What I want to do is use a shell script to select a specific session. Every session will have a closedown shell script which looks similar to this:
#!/usr/bin/env bash
SESSION="InstancesTesting"
echo "checking for session - $SESSION"
SESSIONEXISTS=$(tmux list-sessions | grep $SESSION)
if [ "$SESSIONEXISTS" != "" ]
then
echo "session found"
tmux attach-session -d -t $SESSION
tmux select-window -t '0821'
tmux send-keys -t '0821' 'quit' C-m
tmux select-window -t '0900'
tmux send-keys -t '0900' 'quit' C-m
tmux select-window -t '0901'
tmux send-keys -t '0901' 'quit' C-m
tmux select-window -t '0910'
tmux send-keys -t '0910' 'quit' C-m
tmux select-window -t '0911'
tmux send-keys -t '0911' 'quit' C-m
tmux select-window -t '0920'
tmux send-keys -t '0920' 'quit' C-m
echo "finished shut down call for $SESSION"
else
echo "session not found skipping"
fi
The problem line is
tmux attach-session -d -t $SESSION
When it is run from a shell script, everything after that stops until the session is detached. However, without attaching the session only the windows of the last attached session can be accessed.
I can't simply kill the session at the end of the quit commands because the simular running inside each window can take up to 10 mins to shut down. Neither do I want to wait 10 mins between starting each shutdown. I want to set them all going then wait for the processes to close before doing a reboot.
What I need is to either:
1. Attach a session and allow the script to keep running without pressing ctrl+b D to detach.
or
2. Change the session which is being accessed without actually attaching it like the above example.
I have also tried
tmux switch-client SessionName
tmux switch-client -t SessionName
tmux switch-client -n
All of these return the same result
no current client
I have also tried
tmux send-keys -t 'WindowName' 'tmux choose-session' C-m
tmux send-keys -t 'WindowName' '0' C-m
Unfortunately, this option also states there is no client.
I am sure this must be possible, I am going round in circles, please help
There is no concept of a "selected session", clients have an attached session but outside tmux when you don't specify a session the choice of which to use is made separately each time. See here: https://github.com/tmux/tmux/wiki/Advanced-Use#the-default-target
But you shouldn't need it. You are already using -t to specify the window, use it to specify the session as well:
tmux send-keys -t "$SESSION:8021" 'quit' C-m
You don't need select-window either unless you later plan to attach, and then one select-window at the end would do. See https://github.com/tmux/tmux/wiki/Advanced-Use#command-targets for a description of targets.
You may also find the has-session command useful instead of using grep, or the -F flag to list-sessions.

How can I create multiple tmux sessions containing windows from command line

I am trying to write a template script for a development session using tmux. So i just need to run this script for opening a new dev environment. Each session will have multiple windows - say two. First window(Window1) can be created while creating the detached session as:
tmux new-session -s $TMUX_SESSION_NAME -d -n Window1
(Here TMUX_SESSION_NAME is the argument passed to the script to name the session).
However, how can I create another window under the same session?
Note that I can create it as below but that messes up when creating another session. Although tmux ls shows each session having 2 windows each, the second session contains all the env settings of the first session(Both are for completely different projects)
tmux new-window -n Window2
tmux attach -t $TMUX_SESSION_NAME
I suspect both/all sessions go under the same /tmp/tmux-SOME_ID/default socket and hence this problem.
Note that the first time i start a dev session all is good with both windows.
Any ideas?
TL;DR: probably with something like
tmux new-window -t $TMUX_SESSION_NAME
tmux rename-window -t $TMUX_SESSION_NAME:1 'second'
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 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}

Stop tmux detached session closing when command finishes

When I fire up a new, detached tmux session using something like
tmux new-session -d -s "newname" 'python my file.py'
the tmux session seems to disappear from tmux ls once my python program has finished. I'd like to drop back into a shell. How do I do that?
Use send-keys to run your script in the default shell process in the new window.
tmux new-session -d -s "new name"
tmux send-keys -t "new name:0" "python my file.py" Enter

Resources