199

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
  • 27,777
  • 43
  • 130
  • 199

13 Answers13

294

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,254
  • 1
  • 14
  • 19
Wesley Baugh
  • 3,058
  • 2
  • 12
  • 5
79

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.

Joe Casadonte
  • 1,084
  • 7
  • 4
  • 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
51

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
  • 27,777
  • 43
  • 130
  • 199
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.

Celsius1414
  • 91
  • 1
  • 1
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
Aaron J Lang
  • 385
  • 1
  • 3
  • 7
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,689
  • 14
  • 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
  • 2
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,922
  • 16
  • 8
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,633
  • 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
2

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.

Michał Leon
  • 272
  • 2
  • 10
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
  • 136
  • 1
  • 3
  • 14