检测当前终端是否通过mosh

检测当前终端是否通过mosh

我正在尝试找出一种方法来检测当前终端/连接(以及在 tmux 会话下)是否通过莫什或不。

这个线程,我找到了我当前所在的伪终端会话:

$ tty
/dev/pts/69

所以,我需要一些产生这个伪终端的进程的信息,或者作为子进程拥有这个 tty 的进程的信息。有了这些信息,也许我就能确定它是来自sshd还是mosh……。但我怎样才能做到这一点呢?

另一个挑战: 如果当前的 shell 是在tmux下,检索到的 tty 可能与 sshd/mosh-server 信息不匹配,因为 tmux 还分配了另一个伪终端。无论 tmux 会话是如何创建的,我都需要区分当前的连接是来自 SSH 还是 mosh。怎么可能呢?

一些试验:

(1) 对于SSH,可以找到sshd与tty匹配的进程:

$ ps x | grep sshd | grep 'pts\/27'
 5270 ?        S      0:00 sshd: wookayin@pts/27

这样我就可以知道当前的连接是通过 SSH 进行的。然而,通过mosh,我找不到任何相关信息。

SSH_CLIENT(2) 使用像或 这样的环境变量SSH_TTY可能不起作用,因为 ssh/mosh 都设置了这些变量,甚至在 tmux 会话中也是错误的。

答案1

我对此提出了一个不错的解决方案,并将其包装为一个简单的脚本:是_莫什

#!/bin/bash

has_ancestor_mosh() {
    pstree -ps $1 | grep mosh-server
}

is_mosh() {
    # argument handling
    for arg in "$@"; do
        case $arg in
          -v|--verbose) local VERBOSE=YES ;;
          *) ;;
        esac
    done

    if [[ -n "$TMUX" ]]; then
        # current shell is under tmux
        local tmux_current_session=$(tmux display-message -p '#S')
        local tmux_client_id=$(tmux list-clients -t "${tmux_current_session}" -F '#{client_pid}')
        # echo $tmux_current_session $tmux_client_id
        local pid="$tmux_client_id"
    else
        local pid="$$"
    fi

    local mosh_found=$(has_ancestor_mosh $pid)   # or empty if not found
    if [[ -z "$mosh_found" ]]; then
        return 1;    # exit code 1: not mosh
    fi

    test -n "$VERBOSE" && echo "mosh"
    return 0;        # exit code 0: is mosh
}


sourced=0
if [ -n "$ZSH_EVAL_CONTEXT" ]; then
  case $ZSH_EVAL_CONTEXT in *:file) sourced=1;; esac
elif [ -n "$BASH_VERSION" ]; then
  [ "$0" != "$BASH_SOURCE" ] && sourced=1
else
  case ${0##*/} in sh|dash) sourced=1;; esac
fi
if [[ $sourced == 0 ]]; then
  is_mosh $@
fi

这个想法非常简单:(i)找到附加到当前 tmux 会话的 tmux 客户端,然后(ii)搜索其祖先进程以查找是否存在 mosh 进程。

它可能不完整,具体取决于环境,但我可以成功检测并应用 24 位颜色功能除非它不在 mosh 下运行(因为 mosh 不支持 24 位颜色)。这是一个办法(将这些行添加到您的~/.vimrc):

" 24-bit true color: neovim 0.1.5+ / vim 7.4.1799+
" enable ONLY if TERM is set valid and it is NOT under mosh
function! s:is_mosh()
  let output = system("is_mosh -v")
  if v:shell_error
    return 0
  endif
  return !empty(l:output)
endfunction

function s:auto_termguicolors()
  if !(has("termguicolors"))
    return
  endif

  if (&term == 'xterm-256color' || &term == 'nvim') && !s:is_mosh()
    set termguicolors
  else
    set notermguicolors
  endif
endfunction
call s:auto_termguicolors()

相关内容