170

I would like my default bash shell to go straight into tmux instead of my always having to type tmux every time.

21 Answers21

235

@StarNamer's answer is generally accurate, though I typically include the following tests to make sure that

  1. tmux exists on the system
  2. we're in an interactive shell, and
  3. tmux doesn't try to run within itself

So, I would add this to the .bashrc:

if command -v tmux &> /dev/null && [ -n "$PS1" ] && [[ ! "$TERM" =~ screen ]] && [[ ! "$TERM" =~ tmux ]] && [ -z "$TMUX" ]; then
  exec tmux
fi

References

AdminBee
  • 22,803
user7089
  • 2,879
  • 3
  • 17
  • 14
  • 2
    Nice, I have needed command before but didn't realize it existed. – Freedom_Ben Jun 21 '15 at 00:25
  • I use Linux Mint, which lets you map certain hotkeys to commands, and (un-kosher as it may be to some..) I've got bash shells with commands starting up there, e.g. Win+Alt+B edits my .bashrc. Vim can't open for some reason if the above is at the top of the bashrc. I've wrapped the middle line in another if statement, if [ ! -z "$PS1" ]; then...fi (checking that it's running in interactive mode) – Louis Maddox Aug 02 '15 at 20:03
  • 3
    this exec statement doesn't let you exit tmux without quitting the entire terminal! :| – Louis Maddox Aug 02 '15 at 20:43
  • 8
    @LouisMaddox: exec replaces the current process with a new one - in this case, it replaces the bash login shell with tmux, so when tmux exits then there is no other terminal to fall back to :) – Mark K Cowan Dec 08 '15 at 12:21
  • For those curious, it looks like command -v tests for the existence of tmux in the path. – Eric Hu Feb 19 '18 at 03:55
  • Am i missing something or would this not attach to an existing tmux session? – rjt Feb 19 '19 at 19:57
  • 1
    @rjt That's correct, this starts a new session by design. If you prefer to attach to an existing tmux session simply replace exec tmux with your preferred flavor of tmux attach – user7089 Feb 20 '19 at 12:54
  • @user7089 but this will crash if there is no existing tmux session (e.g. after a reboot) right? – Verena Praher Aug 13 '19 at 08:53
  • 29
    instead of exec tmux I use exec tmux new-session -A -s main so I will always have a session called main and attach to it (instead of creating a new one everytime I connect to my remote machine) but it will not crash like using tmux attach in case there is no session available (found here: https://unix.stackexchange.com/a/176885/256942) – Verena Praher Aug 13 '19 at 08:55
  • @VerenaHaunschmid Nice find. That's a great approach for those who want to re-attach to their existing session – user7089 Aug 13 '19 at 13:41
  • I think this is a great approach. But, sometimes I want to start a bare shell without tmux. Given the suggested setup, what would be the simplest way to do that? – Klas Mellbourn Nov 20 '19 at 23:45
  • @KlasMellbourn wrap the exec tmux command inside an if statement like: read -p "Run tmux? (y/n)" -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then exec tmux fi fi – Tropilio Apr 21 '20 at 16:46
  • @VerenaHaunschmid This loads the vscode/codium terminal in tmux when running the terminal. And I cannot get out of that without leaving the loaded environment that vscode/codium uses. Since I often use codium, I cannot make any tmux default session at start, since anything I do with that session happens in the terminal of vscode/codium as well. – questionto42 Jan 23 '22 at 19:26
  • I'm using vscode just like questionto42 and noticed that when I quit vscode, the session is (as expected) detached... but when I open it back again, it creates a new one. This considered, it seems huangzonghao's answer would be a better solution. – João Ciocca Feb 22 '22 at 16:15
  • This broke my VSCode (which for some reason uses an interactive terminal during startup?) but adding a like "$TERM" =~ dumb fixed the issue. – Thomas Ahle Sep 06 '22 at 18:40
  • i had the same issue, that within vscode a terminal with the tmux session was opened, the same session i used already in my normal terminal, which was not nice, for mitigating this you can see my answer, its basically this answer + vscode without tmux, just scroll down a bit – Elytscha Smith Dec 09 '22 at 17:24
70

Start tmux on every shell login, from Arch wiki, seems to work. Simply add the following line of bash code to your .bashrc before your aliases; the code for other shells is very similar:

[[ $TERM != "screen" ]] && exec tmux
Paulo Tomé
  • 3,782
StarNamer
  • 3,162
44

Adding a line like

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

in your bashrc file will probably do the job. Note this line will exit ssh and terminate the connection once you detach or exit tmux. I like this configuration as it saves key strokes to terminate the connection. But if you don't love this(which I think is very unlikely) and would rather remain in the login shell after termination, just remove the exit part:

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

Also note you shouldn't wrap tmux attach with exec, as this would cause the connection to be closed when there are no tmux sessions to attach to.

hzh
  • 591
  • I've added this line to my .bashrc, but now when I start a terminal, I get some messages: /home/z/.tmux.conf:10: no current session (the message repeats for lines 11, 13, 14, 15). Those lines are things like "set default-command "exec bash"" and "set default-terminal "screen-256color". – Matt G Feb 03 '19 at 02:40
  • @MattG Feel like it's something wrong with the tmux configuration file. – hzh Feb 03 '19 at 18:40
  • I was unable to login with this setting. Running Ubuntu 20.04. – Richard Jan 12 '21 at 18:05
  • @Richard what's the error message? – hzh Jan 12 '21 at 18:59
  • After logging in, something would fail and take be back to the login screen. See my answer for a fix. – Richard Jan 13 '21 at 19:33
  • What is the role of the {} in this command? – Abhilash Oct 11 '21 at 11:45
  • this solution is perfect for using with vscode. When I close vscode the session is detached and stays running. When I open vscode again, it attaches back and I resume from where I left off! Thank you! – João Ciocca Feb 22 '22 at 16:18
  • I would suggest adding [[ -t 0 ]] && at the start of that line, because if this is configured on a server and you try to add an ssh key (ssh-copy-id) or copy a file through scp, it will fail with error opening terminal: not a terminal. This solves the error. The complete line would be: [[ -t 0 ]] && [ -z "$TMUX" ] && { tmux attach || exec tmux new-session;} – Ciro García Dec 12 '23 at 14:21
8

I'm successfully using

case $- in *i*)
    [ -z "$TMUX" ] && exec tmux
esac

in my .zshrc. If you're using bash, put it in your .bashrc instead.


I also just tried setting tmux as my default shell (chsh -s $(which tmux)) and it seems to break direct command execution via SSH, e.g. ssh $some_server echo foo will not produce any output.

n.st
  • 8,128
  • 1
    Why are you using case $- in *i*)? – Ahmad Ismail Jul 08 '22 at 20:34
  • 2
    @AhmadIsmail $- contains the current shell options, including i if the shell is interactive (i.e. a user prompt is requested, rather than directly executing a command). case … in *i*) is a fairly portable way to check if a variable contains the letter i anywhere (no need to break out expr or [[ and regular expressions for something so simple). – n.st Jul 12 '22 at 04:39
  • 1
    And for the last part, $TMUX is set inside tmux sessions, so we can check if it's unset/empty to only spawn tmux if we are not already inside a tmux session. – n.st Jul 12 '22 at 04:40
8

There is command chsh which changes login shell. Consult man chsh.

Make tmux your login shell, but don't forget to configure the default-shell setting for tmux first!

Example of ~/.tmux.conf:

set-option -g default-shell "/bin/bash"

You need to test this first, before setting tmux as your login shell.

Kusalananda
  • 333,661
paul
  • 1,993
  • 7
    tmux is not a shell, it's a terminal multiplexer like GNU screen. Interestingly, it does support the -c option according to the man page, so it may work like a shell just enough to use it as your login shell, but I suspect it won't work properly in all situations, e.g. graphical logins via gdm/kdm. – Mikel Jul 20 '12 at 15:32
  • 2
    Although this is sensible and backed by the documentation, it seems to break direct command execution via SSH (something like ssh $some_server echo foo). – n.st May 11 '14 at 02:11
  • 5
    tmux as of at least 1.8 on Ubuntu adds itself to /etc/shells, so it is a valid login shell. – claytron Mar 26 '15 at 17:14
  • 5
    This requires you configure the default-shell setting in the tmux configuration to point to an actual shell. – Kusalananda Jan 14 '17 at 13:35
8

I combined the extensive checks, with the conditional session checking, and put my own spin on it, to create a default session that is connected to or else created. Unless you are inside of another tmux session, or other protective conditions are met.

if command -v tmux &> /dev/null && [ -n "$PS1" ] && [[ ! "$TERM" =~ screen ]] && [[ ! "$TERM" =~ tmux ]] && [ -z "$TMUX" ]; then
  tmux a -t default || exec tmux new -s default && exit;
fi

Based on these answers:

https://unix.stackexchange.com/a/306165/198110

https://unix.stackexchange.com/a/113768/198110

yosefrow
  • 389
7

Go to terminal preferances. enter image description here

And then click to "command" bar. enter image description here

Check the "Run a custom command instead of my sell" and write whatever command you want to execute at the startup of your terminal.

  • I tried this before getting here. However, I can't use the tmux a || tmux new-session command. When there's a session to connect, it connects, but, otherwise, the terminal closes immediately. This forced me to use another TTY to revert the configuration (which may be scary for newby users). – Heliton Martins Apr 10 '22 at 12:41
3

Adding to @Louis Maddox 's answer, I would execute tmux part with;

(exec tmux attach || exec tmux new-session)
devrimbaris
  • 129
  • 4
  • I use exec sh -c 'tmux a || tmux', which (after looking at your answer) will probably make bad things happen if tmux can't start for any reason..... thanks, I'll use yours from now on :) – Mark K Cowan Dec 08 '15 at 12:22
  • 2
    tmux new -A -s mysession will probably work too. – poolie Apr 22 '16 at 01:16
3

This is in my ~/.profile (I'm using ksh93):

if [[ -z "$TMUX" ]]; then
    if tmux has-session 2>/dev/null; then
        exec tmux attach
    else
        exec tmux
    fi
fi

If the TMUX environment variable is unset/empty, then we're not already in a tmux session, so...

If tmux has-session returns with a zero exit status (true), there is an available session to attach to. Attach to it.

If not, create a new session.

It's also possible to use tmux as your login shell. If you do this, however, make sure to set default-shell to an actual shell in your ~/.tmux.conf file (see the tmux manual for more info about this).

Kusalananda
  • 333,661
2

None of the above responses worked for me - exec tmux prevents me closing tmux without quitting the shell (whether it's opened with Ctrl + T or from the application menu).

I use Linux Mint, which lets you map certain hotkeys to commands, and (un-kosher as it may be to some..) I've got bash shells with commands starting up there, e.g. Win+Alt+B does some sort of convoluted bash -exec(vim) statement to edit my .bashrc, so it acts like a regular shell.

tmux loaded rather than vim under that situation after placing the above at the top of my .bashrc. I've wrapped the tmux executing line in another if statement, checking that it's running in interactive mode.

if command -v tmux>/dev/null; then
        if [ ! -z "$PS1" ]; then # unless shell not loaded interactively, run tmux
                [[ ! $TERM =~ screen ]] && [ -z $TMUX ] && tmux
        fi
fi

You could wrap all that onto one line but for readability I think that's fine.

2

You could (and as of now probably should) use sudo chsh $(logname) command to set /usr/bin/tmux, or whatever is the path to it, as a default shell, then add the following to ~/.tmux.conf:

set-option -g default-shell </path/to/your/favourite/shell>
  • Correct me if I'm wrong, but tmux ain't a shell, is a shell/screen multiplexer. What OP meant by "shell" is launching tmux by default, with the default shell in each pane. Point is, you can't set default-shell to tmux afaik because it ain't a shell and if you could anyway, it could result in tmux complaining about "tmux session inside a tmux session" if you would open a new pane inside tmux which would use the default shell. – Eksapsy May 02 '21 at 12:37
  • @Eksapsy You are wrong. I have had my default shell set to /usr/bin/tmux for the last 5 years and that's how it is supposed to work, it doesn't complain about anything. After it fires up it starts another tmux session (see the second paragraph of https://man7.org/linux/man-pages/man1/tmux.1.html), and using the option mentioned above, it fires up ZSH in that session's window. You can have any binary whatsoever as your a login shell. tmux does handle being login shell without an issue, even when logging in via SSH. – Błażej Michalik May 02 '21 at 13:25
  • @Eksapsy FTR, here's what man tmux says about tmux -c: Execute shell-command using the default shell. If necessary, the tmux server will be started to retrieve the default-shell option. This option is for compatibility with sh(1) when tmux is used as a login shell. – Błażej Michalik May 02 '21 at 13:36
  • Im sorry but to me your instructions didn't work either. tmux doesn't exist as a shell in /etc/shells. I added it manually, even if you're not supposed to do that, and chsh to tmux anyway. Didn't work again. Then added set-option -g default-shell /usr/bin/zsh. Didn't work either. The most important thing here though is, that tmux didn't appear as a shell in /etc/shells at all. Maybe I'm doing something wrong, but it only shows that this is not the default best way to do things? Usually when you install a shell it sets itself inside /etc/shells on its own. – Eksapsy May 02 '21 at 15:23
  • @Eksapsy what exactly didn't work? What have you gotten instead? Where have you added the default-shell command? It's supposed to be in your ~/.tmux.conf – Błażej Michalik May 02 '21 at 15:57
  • @Eksapsy from man chsh: The only restriction placed on the login shell is that the command name must be listed in /etc/shells, unless the invoker is the superuser, and then any value may be added. – Błażej Michalik May 02 '21 at 16:00
  • @Eksapsy This is what my postinstall script for Ubuntu does and it's never been an issue - albeit via usermod, but the end result is exactly the same, i.e. the right line in /etc/passwd has /usr/bin/tmux in the login shell field: https://github.com/MrMino/dotfiles/blob/postinstall/postinstall.sh#L87 – Błażej Michalik May 02 '21 at 16:11
  • Firstly, you're very helpful, thanks! The tmux command was in ~/.tmux.conf, seems like the issue is completely something else. chsh doesn't work in general, not just with tmux. I mean, it changes /etc/passwd but it doesn't change $SHELL. I tried setting the gnome-terminal's command preference to "Run command as a login shell" but that didn't work either. In any case, you've been helpful with your guidance, but this seems like a different issue and it's an issue with my system. So probably continuing this here would be against comment etiquete :P Thanks, learned a new thing or two. – Eksapsy May 02 '21 at 16:46
  • 1
1

I use the following for zsh.

if command -v tmux &> /dev/null && [[ -z "$TMUX" ]]
then
    tmux new-session -c $PWD
fi

The difference with existing solutions being, If you are using a DE and try to use 'Right Click > Open In Terminal' then it will open in current location.

Another difference is, we do not use exec in this particular case. Please read Mark Hansen's Blog titled An Argument for Auto-Starting Tmux.

Some people suggest you exec tmux, this replaces your entire shell's process with tmux, and can fail pretty badly if tmux has errors. At least running tmux directly will fall back to your terminal if tmux has an error. It also makes it easy to drop the tmux session if you don't want it - just detach. The extra process is a small cost to pay.

For Fish shell, I follow similar steps. I put the following in the conf.d:

if status is-interactive
    if not set -q TMUX
        tmux new-session -c $PWD
    end
end

There is also the Tiny Frames problem.

tmux will auto-size its window frame to the size of the smallest terminal attached to the session. Often this results in a tiny laptop terminal window making the usable space on a huge desktop screen tiny.

Even in my machine, connecting to same session via two terminals does not end up well. Same command mirror in both terminals.

Terminal Mirroring

The point is using code like bellow does not work for me.

if tmux has-session 2>/dev/null; then
    tmux attach
else
    exec tmux
fi

So I have a fish script which does the following:

  • if no session then create new session
  • if has unattached session then give option to connect to one of them (after attaching, cd to $PWD)
  • if do not want to attach to unattached session, then create new session

Here is the script (I put it in conf.d):

if status is-interactive
    if not set -q TMUX
        if tmux list-sessions &>/dev/null
            set -l array_unattached
        for i in (tmux list-sessions -F &quot;#{session_attached} #{session_name} \&quot;#{session_path}\&quot;&quot;)
            if test (echo $i | cut -d' ' -f1) -eq 0
                set -a  array_unattached (echo $i | cut --complement -d ' ' -f 1)
            end
        end

        if set -q array_unattached[1]
            set -l selection (printf '%s\n' $array_unattached | rofi -dmenu -p &quot;Select tmux session&quot;)
            if test $status -eq 0
                set -l session_name (echo $selection | cut -d ' ' -f 1)
                tmux send-keys -t $session_name:1.1 &quot;^C&quot;
                tmux send-keys -t $session_name:1.1 &quot;cd $PWD &amp;&gt; /dev/null&quot; ENTER
                tmux attach-session -t $session_name:1.1
            else
                tmux new-session -c $PWD
            end
        end
    else
        tmux new-session -c $PWD
    end
end

end

Ahmad Ismail
  • 2,678
1

Add the below line to ~/.config/fish/conf.d/omf.fish

if not set -q TMUX
    set -g TMUX tmux new-session -d -s base
    eval $TMUX
    tmux attach-session -d -t base
end

The above worked on Fedora 34. However, on exit, only tmux is exited and the running session remains active.

Greenonline
  • 1,851
  • 7
  • 17
  • 23
1

There seem to be two classes of answers here:

  1. Those that just "start tmux" (exec tmux) using various techniques and (preferably) wrappers for error handling. E.g. exec tmux

  2. Those that first attempt to attach to an existing tmux and then fallback to the first method if an existing session doesn't exist. E.g. tmux attach || exec tmux.

This second method can be simplified and made more efficient with:

exec tmux new -A

The -A flag to new (short for new-session):

  • Checks to see if an existing tmux session exists
  • Attaches to it if if so
  • Starts a new session if not

In addition to being more concise than the longer form, it's also theoretically slightly more efficient, since tmux only has to start once, rather than potentially twice (once to check, again to actually run if it wasn't running).

I use a slightly longer form personally:

exec tmux new -AD -t main -s main

This:

  • Makes sure that there is only one session-group and session running (named main)
  • Detaches any other running tmux client.

I do still recommend wrapping this in an if statement per user7089's answer.

NotTheDr01ds
  • 3,547
1

Not quite what the original question asked, but a flexible alternative is to add

history -s "tmux attach"

to your ~/.profile. That way when logging in you can just use the up arrow and enter to start tmux back up.

Daniel
  • 33
0

this make tmux open by default on all new shell of user

cmd='[ $TERM == screen ] || exec tmux'
echo -e "$cmd\n$(cat ~/.bashrc)" > ~/.bashrc
0

I had an issue where I could not login (on Ubuntu 20.04). I added the following tweak to huangzonghao's answer:

# autoload tmux - place at EOF (end-of-file) within ~/.bashrc
# if shell is interactive, and TMUX var is set...
[[ $- == *i* ]] && [[ -z "${TMUX}" ]] && { tmux attach || exec tmux new-session && exit; }
Richard
  • 101
0

if tmux already installed on your system , do this:
sudo usermod -s $(which tmux) USERNAME
now your user configured for use tmux as default shell .

now config tmux as your preferred shell :
set-option -g default-shell "/bin/bash"
or any other configuration you want ....
Note: tmux execute /bin/bash , so /etc/bashrc or $USER/.bashrc loaded immediately .

mah454
  • 308
0

If someone wants to start tmux session always BUT NOT within Visual Studio Code, i did the following.

Its basically the same like @user7089 answer, so for explanation look at his answer, i just added the exclude vscode part

do this in your vscode settings.json

{
...
    "terminal.integrated.profiles.linux": {
        "bash": {
            "path": "bash",
            "icon": "terminal-bash"
        },
    ...
    },
    "terminal.integrated.defaultProfile.linux": "bash",
    "terminal.integrated.env.linux": {
        "LAUNCHED": "vscode"
    },    
}

do this in your ~/.bashrc

if command -v tmux &> /dev/null && [ -n "$PS1" ] &&  [[ ! "$LAUNCHED" == "vscode" ]] && [[ ! "$TERM" =~ screen ]] && [[ ! "$TERM" =~ tmux ]] && [ -z "$TMUX" ]; then
  exec tmux new-session -A -s main
fi
-1

Add this into your ~/.tmux.conf

set -g default-command /usr/local/bin/fish
-3

As Mikel already stated in his comment to have tmux as your login shell can have side effects. But you can make tmux your default shell, literally. A user's default shell is defined in /etc/passwd. So you can become root and edit /etc/passwd, e.g. sudo vi /etc/passwd search for the line that begins with your username. It probably ends with :/bin/bash. Change /bin/bash to /usr/bin/tmux and now tmux is your default login shell.

However, no guarantee that this won't cause problems!

What may work better is to NOT do anything that requries root privileges. I would try to create a file in my home directoy named .bash_login and start tmux from within that file: `echo "tmux" >~/.bash_login.

This should work, but you have to try and find our yourself, b/c the bash documentation is not very exact about what file is read and executed when.

Bananguin
  • 7,984
  • 2
    What your first paragraph describes is what chsh does! Except that your way requires being root and is error-prone. Running tmux from .bash_login is more likely to break remote logins. – Gilles 'SO- stop being evil' Jul 20 '12 at 23:10