1

Setup

I run screen on a local machine and use different screen windows to connect to different hosts. It would be nice to change window names to the host names automatically during the ssh process.

Approaches

I have tried different variations of the 2 approaches below:

1) Using LocalComand in ssh config file:

Host *
PermitLocalCommand yes
LocalCommand '[ "${TERM:0:6}" == "screen" ] && printf "\ek@%h\e\\"

2) Creating a custom bash function:

# function to set screen name based on host and reset on exit
function ssh() {
  echo -e '\033k'@$1'\033\\'
  ssh -Y "$@"
  echo -e '\033k'local'\033\\'
}

Problem

Both of these approaches work but they also seem to interfere with things like auto-completion:

$ scp user@host:~/.s<tab>
...o^[\\\\   ...cal^[\\\\

Question

Is there some condition that could be used (on top of checking if $TERM == screen) that would allow executing the LocalCommand (or the ssh() function) only when connecting to host and not when used for auto-completion?

3
  • Is your problem like problem1 or like problem2? – harrymc Apr 8 '20 at 9:59
  • @harrymc it's both - I want to both set the title when on ssh, and reset after closing. I did achieve it (the function ssh() { is very similar to this answer). The problem I have is that those solutions interfere with autocomplete. i.e. they attempt to set titles even when I run commands (without logging in) via ssh, and pollute the prompt. – Karolis Koncevičius Apr 8 '20 at 10:08
  • Note: the PS1 way of doing this didn't work for me because after ssh'ing to a host, the prompt of that host will attempt to modify the GNU-screen window title ON that host, not the title of my local screen instance. – Karolis Koncevičius Apr 8 '20 at 10:09
1
+100

You need to print these control sequences, so screen captures them; still you must not print them to the stdout of ssh. Print them to stderr. The completion functions that use ssh should capture and use the output only, they should ignore error messages. But when you use ssh normally, screen will get stdout and sterr from ssh.

Your function modified:

# function to set screen name based on host and reset on exit
function ssh() {
  echo -e '\033k'@$1'\033\\' >&2
  command ssh -Y "$@"
  echo -e '\033k'local'\033\\' >&2
}

Note I added the word command. Without it the function would call itself recursively.

The above function relies on $1 being the hostname or so. In general it may not be a case. More robust solution is to change one way using LocalCommand and its %h, then change back to local using a function.

Host *
PermitLocalCommand yes
LocalCommand exec bash -c '[ "${TERM:0:6}" == "screen" ] && printf "\ek@%h\e\\" >&2' ssh-bash

I forced bash to handle the command because ${TERM:0:6} is not portable. LocalCommand uses the user's shell which in general may not support the syntax.

# function to reset screen name on exit
function ssh() {
  command ssh "$@"
  echo -ne '\033klocal\033\\' >&2
}

I removed -Y from the function. Now it's safe to provide it as an argument if needed.

In case printing to stderr interferes with anything else, consider printing directly to /dev/tty (printf … >/dev/tty). This has its own subtleties though.

1
  • Thank you a lot. Very nice and detailed answer, unexpected after a week of silence but very welcome. – Karolis Koncevičius Apr 13 '20 at 6:33

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.