Shell

如何在安裝了fish的遠端伺服器上使用fish而不更改登錄shell?

  • August 7, 2019

我經常ssh在幾個不同的伺服器上,其中一些沒有fish安裝,但很多都安裝了。如果可用,我想獲得fishshell(中途更改總是很乏味,並且您會失去已鍵入內容的歷史記錄),但是更改預設 shell 不是一個好主意,因為:

  • 我需要更換許多不同的機器;
  • 在許多其他上,我通過 LDAP 登錄,並且更改儲存在 LDAP 上的 shell 會在fish不可用的機器上中斷;
  • 一般來說,由於fish不兼容 POSIX-sh,將其作為預設 shell 可能會破壞腳本執行的命令ssh
  • 最後,有幾台機器的使用者與其他人共享(或者,我必須登錄另一個使用者),所以更改預設 shell 不是一個好主意。

因此,理想情況下,我希望有這樣的命令在可用時ssh自動啟動fish,或者只保留提供的任何預設 shell。

經過一些實驗,我整理了fissh腳本:

#!/bin/sh
ssh "$@" -t "sh -c 'if which fish >/dev/null ; then exec fish -li; else exec \$SHELL -li; fi'"
  • "$@"轉發傳遞給的所有參​​數ssh
  • -t強制分配 tty(否則ssh在指定命令時預設為無 tty)
  • sh -c是必需的,因為我們不知道另一端可能有什麼外殼 - 在我的個人機器上,我確實有fish預設外殼,這會因不同的if語法而中斷;
  • which fish如果找到執行檔則成功fish;在這種情況下,它是exec-ed (要求互動式和登錄 shell);
  • 否則,我們回退到$SHELL,這是目前使用者的預設 shell($被轉義,否則它會被sh“在這一邊”擴展)。

-li在任何一種情況下都通過,以確保我們實際上獲得了一個登錄的互動式**shell。雖然-iPOSIX 強制要求任何外殼,-l但“只是”一個常見的擴展,但不將其放入可能會導致不好的意外。

請注意,stdoutofwhich是隱藏的(在正常情況下,我們不關心在哪裡fish找到),但是stderr(在找不到錯誤消息的fish地方)故意保持不變,作為對使用者的警告,儘管我們最好意圖,fish找不到。

為了完成體驗,在我的機器上,fish我通過創建一個~/.config/fish/completions/fissh.fish包含自定義完成的文件來添加對自定義完成的支持

complete -c fissh -w ssh

指示fish具有fisshssh.

引用自:https://unix.stackexchange.com/questions/476107