204

If I use

tmux attach

I can attach to a running session but if there is no session running, I only get the error

no sessions

How can I automatically start a new session if there is none running? something like

tmux attach-or-create-new-session
rubo77
  • 28,966

13 Answers13

302

If naming your session is okay, then it's easy to do with the new-session command:

tmux new-session -A -s main

where main is the session name that will be attached to or created if needed.

From man tmux:

The -A flag makes new-session behave like attach-session if session-name already exists; in this case, -D behaves like -d to attach-session.

This can be shortened to rely on the default session name (which is 0):

tmux new -As0

Please also note that the -A option was introduced in tmux version 1.8 on 26 March 2013. For earlier versions, use:

tmux attach || tmux
Walf
  • 1,321
Wesley Baugh
  • 3,138
80

The answer is much simpler. Just put this in your ~/.tmux.conf file:

# if run as "tmux attach", create a session if one does not already exist
new-session -n $HOST

If you run tmux attach and there is a session, then it will attach to that session (whether it's already attached or not). If there is not a session already then it will create one for you.

  • 19
    this is a neat trick, but there is a caveat: if tmux is invoked without arguments, it will create a new session and then create a second session as soon it reaches this line in your ~/.tmux.conf. You can see this issue by executing tmux ls after creating the first session. In practice, after you put this in your file, you cannot call tmux with no arguments anymore – Bruno Polaco Nov 23 '14 at 23:35
  • 6
    So you would have to add an alias alias tmux="tmux attach" to prevent this problem – rubo77 Mar 21 '15 at 15:07
  • @BrunoPolaco: what is the big caveat with an extra empty tmux session running all the time (apart from that it doesn't look tidy in the task-list)? – rubo77 Sep 26 '16 at 03:14
  • 1
    @rubo77 Resources. Some people have a few default tools, windows, panes, etc created when they launch tmux. – rovr138 Mar 24 '17 at 17:05
52

This will start a new session if attach gives an error:

tmux attach || tmux new

So an alias will do the job:

tm="tmux attach || tmux new"
rubo77
  • 28,966
9

To expand on Wesley Baugh's answer (which was double-nesting sessions for me when used in .bashrc on logins) and add a bit of flexibility since I often use sudo -s on servers (which would dutifully load my .bashrc again and double nest), here's what I have in my .bashrc:

if [ -z "$TMUX" ] && [ ${UID} != 0 ]
then
    tmux new-session -A -s main
fi

This checks for a tmux session and makes sure you aren't superuser before creating a new session or attaching to that existing one named main.

5

If you're using this inside a .shrc file or similar with exec I'd recommend

if tmux ls &> /dev/null; then
  exec tmux attach
else
  exec tmux
fi
4

Consider adding the following to your .bashrc

if [ -z "$TMUX" ]; then
    base_session='my_session'
    # Create a new session if it doesn't exist
    tmux has-session -t $base_session || tmux new-session -d -s $base_session
    # Are there any clients connected already?
    client_cnt=$(tmux list-clients | wc -l)
    if [ $client_cnt -ge 1 ]; then
        session_name=$base_session"-"$client_cnt
        tmux new-session -d -t $base_session -s $session_name
        tmux -2 attach-session -t $session_name \; set-option destroy-unattached
    else
        tmux -2 attach-session -t $base_session
    fi
fi

You can see my use of this in my ZSH resource file at my github repo

sparticvs
  • 2,739
  • 16
  • 22
3

Here is an alternative solution from this blog. Works like a charm.

session="main"

Check if the session exists, discarding output

We can check $? for the exit status (zero for success, non-zero for failure)

tmux has-session -t $session 2>/dev/null

if [ $? != 0 ]; then

Set up your session

fi

Attach to created session

tmux attach-session -t $session

From man page

has-session [-t target-session] (alias: has)
Report an error and exit with 1 if the specified session does not exist.
If it does exist, exit with 0.
Levon
  • 151
3

Use this:

$ tmux a || tmux

The || operator is the opposite of the && operator, meaning the second command is performed if the first one fails.

Make an aliast of it if it's too long.

2

Drew Frank answered this here: https://superuser.com/questions/487363/tmux-equivalent-of-screen-r

Here's the script I now use for this (though, I've switched back to screen due to another issue with tmux) /somewhere/on/your/path/ttmux or as a shell function:

#!/bin/sh
# many thanks to Drew Frank: https://superuser.com/questions/487363/tmux-equivalent-of-screen-r
(tmux ls | grep -vq attached && tmux -2 at) || tmux -2

The -2 options make tmux assume 256 color terminal support, so those may not be appropriate for your situation.

SuperMagic
  • 1,942
2

I improved on @SuperMagic answer a little. I put this block at the top of my .zshrc

if [[ $TMUX = "" ]]; then
  # try to reattach sessions
  tmux ls | grep -vq attached && TMUXARG="attach-session -d"
  exec eval "tmux -2 $TMUXARG"
fi
cmcginty
  • 2,683
  • 4
  • 21
  • 12
2

I did create this function, hope it helps!

tm() {
  local targetSession="$1"
  local DEFAULT_SESSION="main"

[ -z "$targetSession" ] && targetSession="$DEFAULT_SESSION"

tmux attach-session -t "$targetSession">/dev/null 2>&1 ||
tmux new -s "$targetSession">/dev/null 2>&1 }

If any, complete with a list of current tmux sessions

complete -C "tmux ls 2>&1 | cut -d':' -s -f1" tm

EDIT:

_tm.getCurrenSession() tmux display-message -p '#S'

tm() { local targetSession=${1:='main'}

if outside tmux

[[ -z "$TMUX" ]] && tmux new -A -s ${targetSession} && return $?

if [[ "_tm.getCurrenSession" = "$targetSession" ]] then print "You did not move."; return 1 fi

Create session if it doesn't exists

tmux new -d -s ${targetSession} 2>/dev/null

tmux switch-client -t ${targetSession} }

_tm() { (( $CURRENT > 2 )) && return 0

local tmuxList=( tmux ls -F "#{session_name}" )

if outside tmux

[[ -z "$TMUX" ]] && _describe 'command' tmuxList && return 0

local currentSession=( _tm.getCurrenSession ) local actualList=(${tmuxList:|currentSession}) _describe 'command' actualList }

compdef _tm tm

0

Here's a zsh script Eden Berger and I wrote to do this.

If any unused (no clients attached) tmux sessions exist, then tmux will attach to one of them (the first, sorted by their session id). Otherwise, a new tmux session will start.

It also supports skipping tmux altogether if already in a tmux session or if SKIP_TMUX is set. I find the latter useful because this snippet is at the top of my .zshrc. So, to run my terminal without starting or attaching a tmux session, I can run an occasional SKIP_TMUX=1 alacritty.

#!/usr/bin/env zsh

if [ -z $TMUX ] && [ -z $SKIP_TMUX ]; then delimiter="," sessions=$(tmux list-sessions -F "#{session_attached}${delimiter}#{session_id}") unused_sessions=$(echo $sessions | grep ^0) unused_sessions_ids=$(echo $unused_sessions | cut --delimiter=$delimiter --fields=2) sorted_unused_sessions_ids=$(echo $unused_sessions_ids | sort --numeric) first_unused_session_id=$(echo $sorted_unused_sessions_ids | head --lines 1) if [ -z $first_unused_session_id ]; then exec tmux new-session else exec tmux attach-session -t $first_unused_session_id fi fi

0

this help me to open tmux when terminal opened and attach S1 if exist, if not exist: will be created

i have already a session called S1
for attach tmux to this session from .zshrc or .bashrc i'm add this in .zshrc|.bashrc

if [[ ! $TERM =~ screen ]]; then
    tmux attach -t tmux-ay || tmux new-session -s tmux-ay -n win1-ay
fi
nextloop
  • 166