设置
我在本地机器上运行 screen,并使用不同的 screen 窗口连接到不同的主机。如果能在 ssh 过程中自动将窗口名称更改为主机名称,那就太好了。
方法
我尝试了以下两种方法的不同变体:
1)LocalComand
在 ssh 配置文件中使用:
Host *
PermitLocalCommand yes
LocalCommand '[ "${TERM:0:6}" == "screen" ] && printf "\ek@%h\e\\"
2)创建自定义 bash 函数:
# 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\\'
}
问题
这两种方法都有效,但它们似乎也会干扰自动完成之类的功能:
$ scp user@host:~/.s<tab>
...o^[\\\\ ...cal^[\\\\
问题
是否存在一些可以使用的条件(在检查是否的基础上$TERM == screen
),允许仅在连接到主机时执行LocalCommand
(或ssh()
功能),而不是在用于自动完成时执行?
答案1
您需要打印这些控制序列,因此screen
捕获它们;但您仍然不能将它们打印到标准输出ssh
。将它们打印到 stderr。使用的完成函数ssh
应该仅捕获并使用输出,它们应该忽略错误消息。但是当您ssh
正常使用时,screen
将从中获取 stdout 和 sterr ssh
。
您的功能已修改:
# 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
}
注意我添加了单词command
。如果没有它,函数将递归调用自身。
上述函数依赖于$1
主机名等。一般来说,情况可能并非如此。更强大的解决方案是使用LocalCommand
和更改一种方法%h
,然后改回local
使用函数。
Host *
PermitLocalCommand yes
LocalCommand exec bash -c '[ "${TERM:0:6}" == "screen" ] && printf "\ek@%h\e\\" >&2' ssh-bash
我强制bash
处理该命令,因为${TERM:0:6}
它不可移植。LocalCommand
使用用户的 shell,而该 shell 通常可能不支持该语法。
# function to reset screen name on exit
function ssh() {
command ssh "$@"
echo -ne '\033klocal\033\\' >&2
}
我-Y
从函数中删除了它。现在,如果需要,可以安全地将其作为参数提供。
如果打印到 stderr 会干扰其他内容,请考虑直接打印到/dev/tty
( printf … >/dev/tty
)。但这有其微妙之处。