Search code examples
tmux

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


Solution

  • 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.