0

I have set up multiple aliases to ssh to different servers

alias sa="ssh user1@server1"
alias sb="ssh user2@server2"
alias sc="ssh user3@server3"

When I run these commands from tmux, all windows are renamed to ssh, instead of sa,sb,sc. How do I get the alias to show up as the window name instead of the actual process name?

Edit: Using macOS 12.2.1, tmux 3.2a, zsh 5.8

2
  • @KamilMaciorowski: So, do you believe that the OP can solve their program by replacing sa, sb and sc with scripts? Or C programs (that call system("ssh …") )? Mar 7 at 9:49
  • I guess a program (binary executable) named sa will solve the problem. A script (text file with a shebang) may not though (e.g. in my Kubuntu an executable script interpreted by bash is still seen by tmux as bash; I don't know macOS at all). Mar 8 at 8:27

1 Answer 1

0

Preliminary notes

  • Some parts of the analysis (below) apply mainly to Linux.
  • The solution had been tested in Kubuntu 21.10 and published. Only then the OP revealed they are using macOS; it turned out the solution does not work in macOS.
  • I decided not to delete the answer (yet), but please be advised it may or may not work in a non-Linux OS.

tl;dr

alias sa='bash -c '\''exec -a "$0" ssh user1@server1 "$@"'\'' sa'

Or better(?) (unalias sa first, if needed):

sa() {
   bash -c 'exec -a "$0" ssh user1@server1 "$@"' sa "$@"
}

Analysis – what you can do in tmux

tmux by default changes the name of the window according to the executable being run in the active pane. This is governed by the automatic-rename option:

automatic-rename [on | off]
Control automatic window renaming. When this setting is enabled, tmux will rename the window automatically using the format specified by automatic-rename-format. This flag is automatically disabled for an individual window when a name is specified at creation with new-window or new-session, or later with rename-window, or with a terminal escape sequence. […]

I assume you want this setting to stay enabled.

You could rename the window on demand (tmux rename-window sa) and re-enable the setting (tmux set-option -w automatic-rename on) before or after calling ssh. But:

  • if before ssh, then selecting another pane in the same window will make automatic-rename do its job (you probably expect this), but selecting back the pane with ssh will rename the window to ssh, not sa;
  • if after ssh, then selecting another pane in the same window (before ssh finishes) won't rename the window.

There may be other disadvantages; neither method is perfect. Also note if you play with set-option -w automatic-rename in more than one pane then commands in one pane may configure the tmux window differently than the other pane tries to impose. Changing the setting back and forth is not a good solution.

A good solution will make tmux set sa as the title automatically. We need a way to tell tmux to use the string sa instead of ssh. For this we need to learn how tmux knows it's ssh you're running.


Analysis – what tmux knows

tmux provides a terminal for your shell. When the shell spawns ssh, the shell puts itself in the background by making the process group of the ssh the foreground process group. When ssh exits, the shell as the parent process reacts, it puts itself in the foreground by setting its process group as the foreground one. The main purpose of this "juggling" is to make job control work (background processes with stdin still connected to the terminal, in case you fg them; but unable to "steal" input until their process group becomes the foreground process group).

The ability of tmux (or another process) to know the name of the foreground executable is only a useful side effect of this mechanism. Knowing the foreground process group for the terminal it provides, tmux can find the process being the group leader and adjust the title automatically.

The shell does nothing to directly inform tmux what command is being executed. If this was the case, a smart enough shell could pass sa instead of ssh. Your shell decides what process group (and when) becomes the foreground process group associated with the terminal (in tmux context: the pane). By monitoring this, tmux can find the foreground process(es) in the pane.

An alias is not a process. Each of your aliases runs an executable named ssh. tmux has no means to know the alias you used. That's why your windows were renamed to ssh, no matter which alias you used.


Solution

It turns out it's not the name of the foreground executable that really matters to tmux. What matters is the string you can see as the first (some would say "zeroth") null-terminated entry in /proc/PID/cmdline. Usually (by convention) it's the path to the executable or its name; but it can be virtually anything.

There are ways to run ssh (or whatever) and specify a custom string. See Setting the thread /proc/PID/cmdline. In Bash exec -a … can do this. But don't invoke it directly from your interactive shell, because exec will replace the shell with whatever you want to run. Thus you need an extra bash that will be replaced. Example:

bash -c 'exec -a "foo" sleep 300'

The above command invoked in a shell inside tmux will make tmux rename the window to foo (if automatic-rename is on; and you may need to wait few seconds).

A basic alias that uses this approach is:

alias sa='bash -c "exec -a sa ssh user1@server1"'

I notice your aliases work well with additional arguments. I mean e.g. your sa sleep 30 expands to ssh user1@server1 sleep 30 which is a sane command that runs sleep 30 on the server. Our alias does not support this yet. This is the fix:

alias sa='bash -c '\''exec -a sa ssh user1@server1 "$@"'\'' whatever'

where whatever is like the second sh in What is the second sh in sh -c 'some shell code' sh? Personally I prefer passing the desired name instead of whatever:

alias sa='bash -c '\''exec -a sa ssh user1@server1 "$@"'\'' sa'

Or maybe (see DRY):

alias sa='bash -c '\''exec -a "$0" ssh user1@server1 "$@"'\'' sa'

Note sa near the end does not need to match the name of the alias. Here it matches because you want this.

The alias is somewhat complicated. It works, nevertheless it's beyond what aliases are for. An equivalent function may be considered more elegant. This is the function (unalias sa first, if needed):

sa() {
   bash -c 'exec -a "$0" ssh user1@server1 "$@"' sa "$@"
}

Notes

  • exec -a is not portable, it works in Bash, it doesn't work in pure sh. Still the alias itself (or the function itself) is valid in any POSIX-like shell. It calls bash explicitly, no matter what your main shell is.
  • There are other tools that read /proc/PID/cmdline or equivalent information. Our solution may mislead them or users using them. E.g. ps -eo pid,comm,command will print ssh in the comm column, but sa in the command column.
4
  • thank you for the comprehensive analysis. I tried the solution you suggested - both using alias and the function. However I am seeing the same results, that is the window still gets renamed to ssh and not the alias/function name. One thing I missed to mention in the original question, is that I am using zsh, not bash, as my default shell. Not sure if the shell choice between bash and zsh would make any difference though. Mar 8 at 7:27
  • @AbhijeetViswam Cannot replicate. The solution works for me in Bash and in Zsh. My tmux -V returns tmux 3.1c. My bash --version shows 5.1.8. Mar 8 at 7:31
  • @AbhijeetViswam For now I cannot tell why the solution doesn't work for you. In case your Bash is old (buggy?) and your Zsh is new, try replacing bash -c with zsh -c. AFAIK exec -a works in Zsh. Or it can be your tmux does things differently for some reason. Please edit the question and state your OS and its version; and the version of tmux. There are differences between Linux, macOS, another Unix-like OS, WSL, Cygwin, … (example) and maybe your tmux sees the real name despite our efforts. My tests were in Linux (Kubuntu 21.10). Mar 8 at 7:50
  • 1
    @ KamilMaciorowski You are probably right about the OS dependency. I tried it on an Ubuntu VM with the same tmux version and your solution worked fine. Mar 8 at 8:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.