如何在安装了 Fish 的远程服务器上使用 Fish 而不更改登录 shell?

Mat*_*lia 5 shell login ssh fish

我经常ssh在几个不同的服务器上运行,其中一些没有fish安装,但很多都安装了。我希望获得fishshell(如果可用)(中途更改总是很乏味,并且您会丢失已输入内容的历史记录),但更改默认 shell 不是一个好主意,因为:

  • 我需要更换许多不同的机器;
  • 在许多其他设备上,我通过 LDAP 登录,并且更改存储在 LDAP 上的 shell 会在fish不可用的计算机上中断;
  • 一般来说,因为fish与 POSIX-sh 不兼容,将其作为默认 shell 可能会破坏脚本通过 ; 执行的命令ssh
  • 最后,有一些机器与其他人共享用户(或者,我必须登录另一个用户),因此更改默认 shell 不是一个好主意。

因此,理想情况下,我希望有一个类似的命令(如果可用)ssh自动启动fish,或者仅保留提供的任何默认 shell。

Mat*_*lia 2

经过一些实验,我整理了fissh脚本:

#!/bin/sh
ssh "$@" -t "sh -c 'if which fish >/dev/null ; then exec fish -li; else exec \$SHELL -li; fi'"
Run Code Online (Sandbox Code Playgroud)
  • "$@"转发所有参数传递给ssh
  • -t强制分配 tty(否则ssh指定命令时默认为无 tty)
  • sh -c是必需的,因为我们不知道另一端可能有什么 shell - 在我的个人计算机上,我确实有fish默认 shell,这会在不同的if语法上中断;
  • which fish如果找到可执行文件则成功fish;在这种情况下,它是exec-ed (要求交互式和登录 shell);
  • 否则,我们会回退到$SHELL,这是当前用户的默认 shell($被转义,否则它会被sh“on this side”扩展)。

-li无论哪种情况都会传递,以确保我们实际上交互式 shell中登录。虽然POSIX 对任何 shell 都强制要求,但它“只是”一个常见的扩展,但不将其放入可能会导致糟糕的意外。-i-l

请注意,stdoutofwhich是隐藏的(就像在正常情况下我们不关心在哪里fish找到的一样),但是stderr(无法找到的错误消息fish)故意保持原样,以警告用户,尽管我们尽了最大努力意图,fish找不到。

为了完成体验,在我的机器上,我通过创建包含以下内容的文件fish来添加对自定义完成的支持~/.config/fish/completions/fissh.fish

complete -c fissh -w ssh
Run Code Online (Sandbox Code Playgroud)

指示fishfissh具有完全相同的有效完成ssh