0

What I Want

I'm trying to automate connecting to a remote machine in multiple, separate ssh terminals and have independent tmux sessions for each remote terminal while sharing the same windows (i.e. can change session settings and active window/pane without affecting other remote terminals while still having access to the same tmux windows).

I want to do this without changing how the tmux executable is initially run and entirely in a per-user way (all changes limited to /home/$USER/).

How I'm Trying To Accomplish It

Ubuntu 16.04 TMUX 2.1 (from package manager)

I'm using MS's port of ssh (OpenSSH) on my local system (Windows 10).

Currently when I open a remote terminal (or a local terminal for that matter) tmux is launched via ~/.zprofile and creates an entirely new session. I have a ~/.tmux.conf file with the following line:

#(this is a single line in my .tmux.conf, I've broken it up here for readability)

if-shell 'tmux has-session -t theonering' \
    'new-session -t theonering'           \
    'rename-session theonering'

I'm, also setting destroy-unattached on at the session level in that second line, but I left it out for clarity here. It doesn't change the outcome.

What I Expect To Happen

This states, to the best of my understanding, that "if, from a shell, tmux says it has a session named theonering then create a new (unnamed) session and group it with theonering. if tmux does not have a session named theonering renamed the current session to theonering."

What Actually Happens

Now if I connect remotely, detach from the existing session, then run the above command (prefixed with tmux, obviously)? Works great.

But if I put it in my ~/.tmux.conf? bupkiss. It's the same as if the line wasn't there at all. No error, no message, no deviation from stock behavior.

1 Answer 1

1

I found a way to kinda-but-not-really do what I wanted and have used that pretty much since posting this. However, I recently stumped across an apparently completely undocumented feature that makes exactly what I want possible:

function smartgrpsc {
  GRPSC_GID=${1:=grpsc}
  GRPSC_CID=${GRPSC_GID}-$(date +'%H%M%S')
  if ! tmux has-session -t ${GRPSC_GID} &>/dev/null; then
    tmux new-session -d -s ${GRPSC_GID}
  fi
  tmux new-session -d -t ${GRPSC_GID} -s $GRPSC_CID \; set-option destroy-unattached \; attach-session -t $GRPSC_CID
}

if ! [[ -n "${TMUX}" || "${TERM}" =~ "tmux.*" || "${TERM}" =~ "screen.*" ]]; then
  # we are (probably) not in a tmux session
  smartgrpsc
  sleep 5
  exit
fi

The secret sauce is the \;s (escaped semicolons) which causes new-session to pass what follows as a tmux command to the tmux session being created. This solves the chicken-or-the-egg problem I was facing before. It allows me to create a session, change it's settings, and then attach to it by send commands to a new tmux session from the same script that started the session (and thus is running outside the session). This instead of trying to figure out what session I'm inside of after the session starts which doesn't seem to be doable from inside the .tmux.conf.

By placing the above at the top of my .zshrc (or .bashrc, etc):

  1. it will make several checks to see if it is inside a tmux session
  • if not, it runs the smartgrpsc function
    1. generates a session groupname (default in the above case)
    2. generates a session name from the groupname and the current time of day (to prevent session id collisions).
    3. checks if a session beginning with or equaling the group name exists. (This is a unique handling of the session name specific to has-session. Sessions belonging to the group usually begin with the group name. Also poorly documented.)
    • If not, it creates a new named and detached tmux session (using the group name).
    • else nothing
    1. finally, simultaneously:
    • creates another new, detached session in the same group
    • sets that session to self destruct when no more clients are attached
    • attaches to the newly created session.
  • else nothing

The end effect is exactly as I stated in my question above. A detached, running "true" session, and a new "viewer" session for every login that is grouped with that "true" session and can see what it sees... but can also change which window it is viewing without affecting other logins. And when a login logs out that "viewer" session is cleaned up while the "true" session and all other "viewer" sessions continue.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .