Per the documentation, when you create a detached session (new-session -d
), it defaults to a size of 80×24. If you attach with a terminal window that is actually 24 lines high (or 25, since tmux uses one for a status line), then you should find that the below-Vim pane does in fact end up with just five lines.
The problem comes when you attach to the session with a terminal window that is much taller than 24 lines. When you do this, tmux resizes the panes to fill the full terminal window. The lower pane grows past its original five lines when this happens.
One way to work around this problem is to create the detached session with an initial size that matches that of the terminal window from which you will eventually attach to the session. One semi-portable way to do this is to parse the output of stty size
(some shells also provide LINES and COLUMNS parameters (especially when in interactive mode), but these parameters are not always available and reliable in shell scripts).
set -- $(stty size) # $1 = rows $2 = columns
tmux -2 new-session -d -s "$SESSION" -x "$2" -y "$(($1 - 1))" # status line uses a row
The failed to connect to server: Connection refused
message comes from your tmux has-session
command. It is reporting that it there is no existing server. Since you are only interested in the exit code, you can probably just send the output to /dev/null
to avoid seeing it at all. You can also put the command directly into the if
statement:
if tmux has-session -t "$SESSION" 2>/dev/null; then
⋮
fi
Incidentally, you should almost always put your parameter expansions in double quotes (to avoid word splitting and glob expansion). You only have the one parameter and its value (copied from USER
) is (usually) probably safe not to quote, but it is a good habit to always quote your expansions in almost all contexts.
Each tmux pane is an interface for a single pty (pseudo tty). Non-split windows have a single pane; split windows have multiple panes.
tmux does not supply a way to add extra processes to a pane once it has been started with its initial command. It is up to that initial command’s process (usually a shell) to supply job control1 for that terminal.
If you want to clobber whatever is currently running in the pane, you can use respawn-pane -k
to kill the existing command and replace it with a new one (e.g., respawn-pane -t sessionname:0.4 -k 'some -new command'
).
But, if you want to maintain whatever is currently running in the pane, then there may be no better option that simply “typing at it” with send-keys
.
You might script it like this (attach last, because otherwise the script will just wait for you to detach before continuing):
session=whatever
window=${session}:0
pane=${window}.4
tmux send-keys -t "$pane" C-z 'some -new command' Enter
tmux select-pane -t "$pane"
tmux select-window -t "$window"
tmux attach-session -t "$session"
Note that, on the send-keys
command, you should actually type the letters
E n t e r,
to tell tmux
to send a newline key to the window.
(Naturally, every command ends with the Enter key.)
1Job control is the arbitration between multiple process groups of a single session that uses the tty as its controlling terminal. I.e., the Ctrl+Z suspend key, and the jobs
, fg
, and bg
shell commands.
Best Answer