我经常ssh
在几个不同的服务器上,其中一些没有fish
安装,但很多都安装了。如果可用,我想获得fish
shell(中途更改总是很乏味,并且您会丢失已键入内容的历史记录),但是更改默认 shell 不是一个好主意,因为:
- 我需要更换许多不同的机器;
- 在许多其他上,我通过 LDAP 登录,并且更改存储在 LDAP 上的 shell 会在
fish
不可用的机器上中断; - 一般来说,由于
fish
不兼容 POSIX-sh,将其作为默认 shell 可能会破坏脚本执行的命令ssh
; - 最后,有几台机器的用户与其他人共享(或者,我必须登录另一个用户),所以更改默认 shell 不是一个好主意。
因此,理想情况下,我希望有这样的命令在可用时ssh
自动启动fish
,或者只保留提供的任何默认 shell。
经过一些实验,我整理了
fissh
脚本:"$@"
转发传递给的所有参数ssh
-t
强制分配 tty(否则ssh
在指定命令时默认为无 tty)sh -c
是必需的,因为我们不知道另一端可能有什么外壳 - 在我的个人机器上,我确实有fish
默认外壳,这会因不同的if
语法而中断;which fish
如果找到可执行文件则成功fish
;在这种情况下,它是exec
-ed (要求交互式和登录 shell);$SHELL
,这是当前用户的默认 shell($
被转义,否则它会被sh
“在这一边”扩展)。-li
在任何一种情况下都通过,以确保我们实际上获得了一个登录的交互式shell。虽然-i
POSIX 强制要求任何外壳,-l
但“只是”一个常见的扩展,但不将其放入可能会导致不好的意外。请注意,
stdout
ofwhich
是隐藏的(在正常情况下,我们不关心在哪里fish
找到),但是stderr
(在找不到的错误消息的位置fish
)故意保持不变,作为对用户的警告,尽管我们最好意图,fish
找不到。为了完成体验,在我的机器上,
fish
我通过创建一个~/.config/fish/completions/fissh.fish
包含自定义完成的文件来添加对自定义完成的支持指示
fish
具有fissh
与ssh
.我认为这个(未经测试的)小期望脚本会做同样的事情:
假设: