64

Instead of having to type tmux every time, how could I have tmux always be used for new session windows?

So if I have no terminal windows open and then I open one, how can that first session be in tmux?

Seems like a .bashrc sort of thing perhaps?

prayagupa
  • 30,204
  • 14
  • 155
  • 192
Michael Durrant
  • 93,410
  • 97
  • 333
  • 497

11 Answers11

68

warning this can now 'corrupt' (make it unable to open a terminal window - which is not good!) your Ubuntu logins. Use with extreme caution and make sure you have a second admin account on the computer that you can log into in case you have the same problems I did. See my other answer for more details and a different approach.

Given that warning, the simplest solution can be to append the tmux invocation to the end of your .bashrc, e.g.

alias g="grep"
alias ls="ls --color=auto"

# ...other stuff...

if [[ ! $TERM =~ screen ]]; then
    exec tmux
fi

Note that the exec means that the bash process which starts when you open the terminal is replaced by tmux, so Ctrl-B D (i.e. disconnect from tmux) actually closes the window, instead of returning to the original bash process, which is probably the behaviour you want?

Also, the if statement is required (it detects if the current bash window is in a tmux process already) otherwise each time you start tmux, the contained bash process will attempt to start its own tmux session, leading to an infinite number of nested tmuxen which can be, err, quite annoying (that said, it looks cool).


However, there is a very small risk this can make bash behave in a way that other programs don't expect, since running bash can possibly cause it to turn into a tmux process, so it might be better to modify how you start your terminal emulator.

I use a small executable shell script ~/bin/terminal (with ~/bin in $PATH, so it is found automatically) that looks a bit like:

#!/bin/sh
exec gnome-terminal -e tmux

(I don't use gnome-terminal, so you might have to remove the exec, I'm not sure.)

Now whenever you run the terminal scipt you have a terminal with tmux. You can add this to your menu/desktop/keyboard shortcuts to replace the default terminal.

(This approach also allows you to more easily customise other things about the terminal emulator later, if you ever desire.)

Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
huon
  • 94,605
  • 21
  • 231
  • 225
  • 1
    How does one get around the fact that this can create a ton of sessions if you are opening/closing terminal windows frequently? – doremi Oct 24 '13 at 19:18
  • 4
    Is it note better to put the line at the start of the file? If the process is replaced, then all changes made by the `.bashrc` are lost. Then the `.bashrc` is sourced again when `tmux` spawns `bash` again. Why run it twice!? – Graeme Mar 02 '14 at 02:46
  • 1
    `exec gnome-terminal -e tmux` FTW – Thomas G Henry LLC Dec 09 '16 at 17:25
  • What if you don't want to replace bash? Remove exec? – Brady Dean Jan 06 '17 at 00:04
  • In Fedora 25, I was getting a login loop when I had `exec tmux` in my `.bashrc`. Since I had already set `Super`+`C` as a keyboard shortcut to launch terminal, I added `-e tmux` to the shortcut command to easily start a tmux session. Specifically, I have the shortcut set to execute `gnome-terminal --window --full-screen -e tmux` – MountainDrew Feb 22 '18 at 16:37
  • I installed tilda for ubutu as a backup terminal just in case of emergency :) Thanks for the warning – Natus Drew May 25 '20 at 23:47
17

My original, accepted answer, stopped working on my Ubuntu14 system after a recent upgrade.

Using either

[ -z "$TMUX" ] && command -v tmux > /dev/null && TERM=xterm-256color && exec tmux

or

[ $TERM != "screen" ] && TERM=xterm-256color && exec tmux

would stop me from being able to even login. I was only able to resolve this due to having a second admin login on the computer.

The fix for me on Ubuntu (and in osx too) was to change my terminal program to actually run tmux instead, i.e.

enter image description here

I still have

[ `uname -s` != Linux ] && exec tmux

as my last .bashrc line but that his only for my Mac OSX systems now.

Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
14

If you want to have a single tmux session, put the following in your ~/.bashrc for bash or ~/.zshrc for zsh:

tmux attach &> /dev/null

if [[ ! $TERM =~ screen ]]; then
    exec tmux
fi

The tmux attach line is to make sure if there is a session it attaches to and if there was no session you will not get the warning about "no session".

K.H.A.
  • 376
  • 3
  • 12
9

For me, I would love my tmux to be started every time I shell onto my remote machine, and when I detach or exit from tmux, the connection should be closed automatically. After digging into this issue for a while, the following code does exactly what I want and is believed to be the most optimized to the best of my knowledge.

[ -z "$TMUX"  ] && { tmux attach || exec tmux new-session && exit;}

Note this line should be the first line in you bashrc file to make sure it is loaded first. We can't put an "exec" call in front of "tmux attach" because after the exec replaces the bash process with the tmux one, the connection will be closed even if there are no sessions to attach to. Therefore we need an "exit" call to terminate the connection after we detach or exit from the attached sessions. But putting an "exec" in front the new-session command is fine as that's the last command to be executed.

hzh
  • 342
  • 2
  • 15
  • This is the one that works best for me - some of the others reattach to tmux but start a new window every time I login. – DavidC Mar 04 '19 at 10:17
  • @huangzonghao This worked fine for me for a day or so, then I started to get: no sessions. server exited unexpectedly. Connection to db-server closed. – henrikstroem Feb 03 '21 at 10:02
  • @henrikstroem did you happen to make some modification to the shell running on the machine? Because "no session" error seems to be triggered by running `tmux attach` without a existing tmux session. However if the `[ -z "$TMUX" ]` is evaluated correctly, `tmux attach` should not be called if there were no tmux sessions. – hzh Feb 03 '21 at 15:49
  • @huangzonghao No, it's actually the only thing in the `.profile` file (it's an ash shell on Alpine). – henrikstroem Feb 03 '21 at 15:53
  • @henrikstroem well in that case I am not familiar with the shell your are using. my guess is that the `server exited unexpectedly` might be the one causing the problem. look into that may be giving more hints to the issue. To stay in connection and avoid `Connection to db-server closed`, just remove the `exit` command from the line. – hzh Feb 03 '21 at 16:11
  • @huangzonghao Yes, that was also my work-around until I figure out what's going on. – henrikstroem Feb 03 '21 at 21:37
3

Append following line of code to the end of .bashrc,

[[ $TERM != "screen" ]] && exec tmux
prayagupa
  • 30,204
  • 14
  • 155
  • 192
3

I just made it a keyboard shortcut (in Linux Mint not Ubuntu; so I'm not sure if it is this easy)...


custom shortcut for tmux terminal


It might be hard to see, but the custom shortcut is gnome-terminal --window --maximize -e tmux. This starts a new gnome-terminal window maximized and then executes tmux for you.

I additionally have another custom shortcut that starts a "normal" gnome-terminal maximized (it's the same without the -e tmux).

I feel this is the best way because you can start whatever terminal whatever way you want and is the most customizable way.

dylnmc
  • 3,810
  • 4
  • 26
  • 42
3

I started with this https://wiki.archlinux.org/index.php/Tmux#Bash and enhanced it to reclaim detached sessions and make new ones if all sessions were already attached

# .bashrc

case $- in
    *i*)
    if command -v tmux>/dev/null; then
        if [[ ! $TERM =~ screen ]] && [[ -z $TMUX ]]; then
          if tmux ls 2> /dev/null | grep -q -v attached; then
            exec tmux attach -t $(tmux ls 2> /dev/null | grep -v attached | head -1 | cut -d : -f 1)
          else
            exec tmux
          fi
        fi
    fi
    ;;
esac
Lee Ballard
  • 1,049
  • 11
  • 13
  • remove the grep and params to "tmux attach" if you always want to attach (from multiple machines at the same time) – Akom Mar 19 '18 at 17:43
2

To enable tmux for login and ssh sessions, you can add this to the end of your .bashrc:

# enable tmux at login
PNAME="$(ps -o comm= $PPID)";
if [ $PNAME == "login" ] || [ $PNAME == "sshd" ] ; then
  exec tmux
fi

This script looks for the parent process of the bash shell. If bash was started from logging in or from ssh, it will execute tmux. If you want this to work with a GUI terminal, you can add that in there as well. For example, if you want to start tmux automatically when you start Ubuntu's standard gnome-terminal, you would use this:

PNAME="$(ps -o comm= $PPID)";
if [ $PNAME == "login" ] || [ $PNAME == "sshd" ] || [ $PNAME == "gnome-terminal" ] ; then
  exec tmux
fi

I've tested the above on Live Ubuntu Desktop and I was able to log in afterwards. This should not break the GUI login unless it invokes the login command to log in. I am not aware of a linux GUI that does this.

ekrekeler
  • 122
  • 1
  • 7
2

Within xfce4 (I'm running Fedora 24 XFCE spin, it's great), I've found the simplest solution is to edit panel shortcuts to so they run:

xfce4-terminal -e tmux

This same command can be used to replace the Keyboard Application Shortcut.

I had previously inserted an if statement into my .bashrc, but it caused login to fail (loop back to the login box whenever a correct password was entered).

The command for Thunar's Open Terminal Here command differs slightly. To change that goto:

Thunar > Edit > Configure Custom Actions... > Open Terminal Here > Edit button, and replace:

exo-open --working-directory %f --launch TerminalEmulator

with: xfce4-terminal --working-directory %f -e tmux

Duncan Betts
  • 33
  • 1
  • 5
1

A one-liner that also makes sure the terminal type is set correctly for 256 colors:

[ -z "$TMUX" ] && export TERM=xterm-256color && exec tmux
Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
0

How about adding

# If not running interactively, do not do anything
[[ $- != *i* ]] && return
[[ -z "$TMUX" ]] && exec tmux

to your .bashrc. It also works for zsh.

Taken from https://wiki.archlinux.org/index.php/Tmux#Start_tmux_with_default_session_layout

theDrifter
  • 1,631
  • 6
  • 24
  • 40