Bash

如何在登錄系統時自動將 bash readline 設置為 vi 模式?

  • March 3, 2018

我的團隊負責數以千計的 Linux/Unix 機器,因此 root 帳戶自然是在管理員之間“共享”的。我更喜歡 vi 模式,其他人更喜歡 emacs 模式。

如何在 SSH 登錄到任何機器時將 bash 的 readline 設置為 vi 模式,而不強迫其他人也使用 vi 模式?

本質上希望具有set -o vi登錄後的效果,而不必每次都實際輸入,也不必強加給其他人(儘管 emacs 模式對我來說很煩人,vi 模式對他們來說很煩人)。

我知道如果每個人都使用自己的帳戶和 sudo 來執行特權命令,這不會是一個問題,但由於我無法控制的情況,這很遺憾不是一個選擇。

這是一種愚蠢的方法,它實際上只適用於公鑰身份驗證:

首先,確保您的本地電腦nc上有它。

其次,仍然在您的本地機器上,製作一個腳本(我會稱之為connect-to-server)並將其放在您${PATH}知道的地方*:

#!/bin/sh
# connect-to-server
ssh -q server-hostname "touch .yourname" </dev/null >/dev/null 2>&1
nc server-hostname 22

接下來,修改.bashrc遠端系統上的 以包含某處:

# partial .bashrc
if [ -f "${HOME}/.yourname" ]; then
 rm "${HOME}/.yourname"
 set -o vi
fi

最後,回到你的本地機器,編輯~/.ssh/config添加:

# partial ssh config
Host serverNickname
 Hostname server-hostname
 ProxyCommand connect-to-server

這種方法的缺點(以及為什麼我稱之為愚蠢):

  • 如果需要實際的代理命令,它會變得更加複雜。
  • 如果其他人在您登錄的同時登錄,則該.yourname文件可能尚未被刪除,在這種情況下,他們也會得到該文件set -o vi
  • 最重要的是,如果您這樣做ssh serverNickname commandcommand則將執行,但是(因為.bashrc從未獲取過)該.yourname文件仍然存在,因此在您的 ssh 配置中使用不使用偽代理的第二個別名是有禮貌的。

事實上,這種方法的唯一好處是您的ssh命令不需要提供任何額外的參數。


*如果您不想更改遠端系統上的任何內容,這裡有一個替代的偽代理,它創建一個臨時的.bashrc

#!/bin/sh
# connect-to-server
ssh -q server-hostname 'ln .bashrc .bashrc.real; cat .bashrc.real <(printf "set -o vi; ln -f .bashrc.real .bashrc\n") >.bashrc.yourname; ln -f .bashrc.yourname .bashrc' </dev/null >/dev/null 2>&1
nc server-hostname 22

這與其他方法具有所有相同的缺點,因此您仍然需要在ssh配置中使用不呼叫偽代理的第二個別名。

我會去:

ssh server -t "bash --login -o vi"

但如果你是管理員,你可以嘗試一些更乾淨的東西。例如,您可以SendEnv在客戶端使用 ssh 選項來傳輸特定變數,AcceptEnvsshd配置(伺服器端)中使用來接受它,並在此基礎上修改 root 的.bashrc文件以根據變數的值調整行為。

這意味著要更改sshd所有主機上的配置以及它們的.bashrc. 然而,這並不完全是一種“獨立”的方式……

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