How to create new tmux session if none exists
I am trying to figure out how to attach to a tmux session
if a named tmux session exists, if not I want to create a new one with the given name.
Currently, I know of a few tmux
commands which can partly achieve what I am looking for, but its not clear how to combine them together to get what I am looking for:
tmux attach
attaches to an automatically existing session - but errors out if no session existstmux new
creates a new session - but it does so every time, so I can't leave it in my.tmux.conf
tmux has-session
tests whether a session exists - but I don't know how to开发者_如何学C stitch it together with the other commands
Thus, I would like to create a tmux script, so that this happens automatically, instead of having to manually create it everytime I need to log into a sessions.
How can I write a automatic script so as to create a new tmux session (if a given session name doesnt exist) or attach to a session name (if it exists)?
I figured it out (and had it pointed out to me).
tmux attach || tmux new
Alternately, you can add
new-session
to your .tmux.conf
- that will create a default session on server start.
Then tmux attach
will either attach to the current session (running server, that is), or create a new session (start the server, read the config file, issue the new-session
command) and attach to that.
As pointed out in comments from Petr Viktorin, jkoelker and pjincz, you can use the following command to attach to mySession
if it exists, and to create it if it doesn't:
tmux new -A -s mySession
From man tmux
:
new-session
[-AdDEP] [-c
start-directory
] [-F
format
] [-n
window-name
] [-s
session-name
] [-t
group-name
] [-x
width
] [-y
height
] [
shell-command
]
(alias:
new
)Create a new session with name
session-name
.[...]
The
-A
flag makesnew-session
behave likeattach-session
ifsession-name
already exists; in this case,-D
behaves like-d
toattach-session
.
new-session
has supported -A
since tmux-1.8.
Adapting Alex's suggestion to include project based configuration upon startup, I started using the following:
# ~/bin/tmux-myproject shell script
# The Project name is also used as a session name (usually shorter)
PROJECT_NAME="myproject"
PROJECT_DIR="~/myproject"
tmux has-session -t $PROJECT_NAME 2>/dev/null
if [ "$?" -eq 1 ] ; then
echo "No Session found. Creating and configuring."
pushd $PROJECT_DIR
tmux new-session -d -s $PROJECT_NAME
tmux source-file ~/bin/tmux-${PROJECT_NAME}.conf
popd
else
echo "Session found. Connecting."
fi
tmux attach-session -t $PROJECT_NAME
where tmux-myproject.conf
is my startup series of tmux commands to create my windows and panes, as well as start my editors.
Although I find rampion's answer is sufficient for using 1 session, this script lets you setup multiple sessions:
SESSIONS="work play"
function has-session {
tmux has-session -t $1 2>/dev/null
}
function except
{
if [ "$?" -eq 1 ] ; then
$1
fi
}
# Configure your sessions here
function session-work
{
tmux new-session -d -s work
tmux neww -k -t work:1
}
function session-play
{
tmux new-session -d -s play
tmux neww -k -t play:1
}
#
#MAIN
for x in $SESSIONS
do
echo $x
has-session $x
except session-$x
done
NOTE:
-k --> new-window will not be created if already exists
-d --> start session or window, but don't attach to it yet
-s --> name the session
-t --> specify a target location in the form session:window.pane
I use an alias to create a new session if needed, and attach to my default session if it already exists:
alias tmuxre='tmux new-session -t default || tmux new-session -s default'
I added this to my .login on my server.
The reason I do it this way is because I don't want to attach to the same actual session, I want a new session which uses the same group of windows.
This is also similar to running screen -xRR
.
For those who want to do the same thing in fish
:
tmux attach -t mysesh; or tmux new -s mysesh
(edit: A solution considering named sessions is mentioned at the end of this answer)
I came across this question when I was looking for a particular use-case, but couldn't find any solutions to it, so I'll add mine here:
Upon terminal-launch tmux should:
- check whether there are any unattached sessions and use the first it can find (each session will be attached only once)
- if there are no unattached sessions create a new one
After reading through the tmux man-pages and looking up arrays in bash I was able to come up with the following one-liner:
tmux attach -t ${$(tmux list-sessions -F '#{session_name}' -f '#{==:#{session_attached},0}')[1]} || tmux new
Explanation:
tmux attach -t $A
: attach to session with content of variable A (in our case the return value of the list-session command + array-index call)tmux new
: create new sessiontogether ->
tmux attach -t $A || tmux new
: if tmux attach fails, create a new session
The next part (our $A) is finding an unattached session:
A = ${$B[1]}
: return the second element in the list B (first one seems to always be an empty string)B = tmux list-sessions -F '#{session_name}' -f '#{==:#{session_attached},0}'
tmux list-sessions
: list all sessionstmux list-sessions -F '#{session_name}
: -F stands for format and-F '#{session_name}'
tells tmux to only show the name of the session and nothing else when it outputs the listtmux list-sessions -f '#{==:#{session_attached},0}'
: -f stands for filter and-f '#{==:#{session_attached},0}'
tells tmux to show only those list-elements, where thesession_attached
-value is equal to 0tmux list-sessions -F '#{session_name}' -f '#{==:#{session_attached},0}'
: both flags in combination will output only the session name and only for those elements of the list, where thesession_attached
-value is equal to 0 (=unattached sessions)
Example:
My application was for WSL, so I added it to the launch of my Ubuntu profile inside the settings.json of Windows Terminal:
"commandline": "C:\\Windows\\system32\\wsl.exe -d Ubuntu-22.04 tmux attach -t ${$(tmux list-sessions -F '#{session_name}' -f '#{==:#{session_attached},0}')[1]} || tmux new",
Edit:
If you have ([a-zA-Z]) named sessions you can sort the list to put those at the beginning:
tmux attach -t ${$(sort -n <<<"${$(tmux list-sessions -F '#{session_name}' -f '#{==:#{session_attached},0}')[*]}")[1]} || tmux new
If you add tmux new -s "primary" ||
at the beginning of the previous command it will try to create the session with the name "primary" and if it already exists it will only attach to it if it is still unattached, otherwise it will take another unattached session (prioritizing named over unnamed) or just create a new unnamed session if there are no unattached sessions left.
Caveat: each time you run this command and "primary" already exists it will output an error-message that it wasn't able to create a session called "primary" (only visible for a split second)
edit edit:
you can redirect those messages by using &> /dev/null
:
(tmux new -s primary || tmux new -s secondary || tmux new -s tertiary) &> /dev/null || tmux attach -t ${$(sort -n <<<"${$(tmux list-sessions -F '#{session_name}' -f '#{==:#{session_attached},0}')[*]}")[1]} || tmux new"
精彩评论