Reputation: 29498
I'm writing a shell script that creates / attaches or switches to a given session, depending on whether one is inside tmux and the session exists.
I've got everything working great except for the case requiring the creation of a new tmux session from within a tmux session.
When my script executes tmux new-session -s name
, I get the following output:
sessions should be nested with care, unset $TMUX to force
I don't actually want to nest sessions, my goal is to create another separate session and switch to it from within a tmux session.
Is this possible?
Upvotes: 159
Views: 147899
Reputation: 63349
I created a zsh/zle
function tmx
:
When invoked from the command line as just tmx
or using a bound key (my case below F4
) it invokes fzf to quickly switch to available tmux sessions with auto-completion and session preview on the right.
(The function was inspired by https://waylonwalker.com/tmux-fzf-session-jump/, see also Quick jump to tmux session.)
When invoked as tmux my-session
it attaches to or creates a new session my-session
.
It works both within and outside an existing session. If invoked within a session it switches the client.
function tmx {
[ -n "$ZLE_STATE" ] && trap 'zle reset-prompt' EXIT
local tmux item
tmux="$(which tmux)" || return $?
if [ -z "$1" ] ; then
item="$($tmux list-sessions -F '#{session_name}' |\
fzf --header jump-to-session --preview "$tmux capture-pane -pt {}")" || return 2
else
item="$1"
fi
(
# Restore the standard std* file descriptors for tmux.
# https://unix.stackexchange.com/a/512979/22339
exec </dev/tty; exec <&1;
if [ -z "$TMUX" ] ; then
# Running insided tmux.
$tmux new-session -As "$item"
else
# Attempt to create a new session in case there none with that name.
$tmux new-session -ds "$item" 2>/dev/null || true
$tmux switch-client -t "$item"
fi
)
}
zle -N tmx
bindkey '\eOS' tmx # Bind the function to F4.
Upvotes: 0
Reputation: 634
tmux switchc -t `tmux new -dP`
To create a new session and switch to it, from insde a tmux session and without using tmux commands, you need to do it in two steps.
new-session
in a detatched way with -d
, print out the name with -P
. Capture this output.NEW_SESSION=`tmux new-session -dP`
switch-client
. Pass your new session as the target with -t
.tmux switch-client -t $NEW_SESSION
You can create a one-liner that does this:
tmux switch-client -t `tmux new-session -dP`
or in shorthand:
tmux switchc -t `tmux new -dP`
Upvotes: 9
Reputation: 551
This script will check if a session exists. If session does not exist create new session and attach to it. If session does exist nothing happens and we attach to that session. Feel free to replace `~/development' with project name.
$ touch ~/development && chmod +x ~/development
# ~/development
tmux has-session -t development
if [ $? != 0 ]
then
tmux new-session -s development
fi
tmux attach -t development
Let's create two detached sessions, list them, attach to one and then from within tmux cycle through sessions.
tmux new -s name -d
works from inside tmux because we're creating a new detached session. Otherwise you'll get a nesting error.
$ tmux new -s development -d
$ tmux new -s foo -d
$ tmux ls
> development: 1 windows (created Wed Jan 13 11:31:38 2016) [204x54]
> foo: 1 windows (created Wed Jan 13 11:31:38 2016) [204x54]
$ tmux attach -t
$ tmux ls
> development: 1 windows (created Wed Jan 13 11:31:38 2016) [204x54] (attached)
> foo: 1 windows (created Wed Jan 13 11:31:38 2016) [204x54]
We are now inside or better known as attached to our target session. If we try to create a new session while attached it will result in a nesting error.
$ tmux new -s bar
> sessions should be nested with care, unset $TMUX to force
To solve this we create a new detached session. e.g.,
$ tmux new -s bar -d
$ tmux ls
> development: 1 windows (created Wed Jan 13 11:31:38 2016) [204x54] (attached)
> foo: 1 windows (created Wed Jan 13 11:31:38 2016) [204x54]
> bar: 1 windows (created Wed Jan 13 17:19:35 2016) [204x54]
Cycle (switch) Sessions
Prefix
(
previous sessionPrefix
)
next sessionnote: Prefix
is Ctrl-b
by default. You can bind Prefix
to Ctrl-a
and in Mac OSX you can change Caps Lock to ctrl system preferences > keyboard > modifier keys
Trying to attach to a session without detaching will result in an error.
$ tmux attach -t development
> sessions should be nested with care, unset $TMUX to force
Instead use command mode Prefix
:
then type attach -t session_name
and hit enter.
Upvotes: 54
Reputation: 130
at user2354696's advice I use following key bindings to create a new session or "clone" an existing session
bind-key N run-shell 'TMUX= tmux new-session -d \; switch-client -n' bind-key C run-shell 'TMUX= tmux new-session -t $(tmux display-message -p #S) -s $(tmux display-message -p #S-clone) -d \; switch-client -n \; display-message "session #S cloned"'
Upvotes: 8
Reputation: 7121
All the commands you can launch within your terminal, like tmux new -s sessionName
can be launched from within tmux
by pressing the trigger key (eg: ctrl-b
) then :
then the command without the starting tmux
part.
As a result, ctrl-b :
followed by new -s sessionName
will do exactly what you want and give a name to your session. It also switches automatically to the new session.
Upvotes: 20
Reputation: 3208
The quickest way (assuming you use ctrl-b
as your command prefix) is:
ctrl-b :new
To create a new session, then
ctrl-b s
to interactively select and attach to the session.
Upvotes: 233
Reputation:
Using this works for me:
TMUX= tmux new-session -d -s name
tmux switch-client -t name
The TMUX=
on the first line is required so tmux doesn't throw a sessions should be nested with care, unset $TMUX to force
message.
Upvotes: 30