207

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
1

13 Answers 13

305

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
8
  • 2
    In my alias list: alias "tmux-attach-or-create-main-session=tmux new-session -A -s main". Thanks for the tip! Manual page: openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1 Commented Oct 14, 2015 at 10:40
  • 3
    [ -z "$TMUX" ] && exec tmux new -As . this is what I use in my .bashrc.
    – ryenus
    Commented Nov 24, 2017 at 3:26
  • 1
    +1 for pointing to an intrinsic feature which eliminates the need for shell-specific scripting. Commented Jun 16, 2018 at 21:47
  • 3
    As screen-transitioner, this command is way too long compared to screen -xR main. It can be shortened to tmux new -As main, which is acceptable with only 2 extra characters.
    – BlackShift
    Commented Jan 7, 2019 at 11:35
  • 5
    If you usually only work with one session, it's default name is 0, so you can do: tmux new-session -A -s 0. Commented Mar 31, 2019 at 12:19
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.

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 Commented Nov 23, 2014 at 23:35
  • 6
    So you would have to add an alias alias tmux="tmux attach" to prevent this problem
    – rubo77
    Commented Mar 21, 2015 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
    Commented Sep 26, 2016 at 3:14
  • 1
    @rubo77 Resources. Some people have a few default tools, windows, panes, etc created when they launch tmux.
    – rovr138
    Commented Mar 24, 2017 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"
5
  • You can even make it shorter by changing tmux attach for tmux a Commented Nov 24, 2014 at 10:46
  • While this is functional, Wesley Baugh's solution uses tmux's built-in functionality to do the same thing Commented Mar 21, 2015 at 14:08
  • fwiw this does seem like the best answer for older versions, before -A was introduced (e.g. v1.6) Commented Jan 16, 2019 at 14:35
  • Do you need the "new"?
    – rubo77
    Commented May 16, 2021 at 17:15
  • 1
    tmux a || tmux
    – Arnie97
    Commented Dec 10, 2022 at 11:20
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
3
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

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

1
  • 1
    this is what I needed for connecting to Centos 7. [omitting the alternate gave me an exit] Commented Jun 4, 2021 at 16:33
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.

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

You must log in to answer this question.

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