私のチームは何千ものLinux/Unixマシンを担当しているので、当然、rootアカウントは管理者間で「共有」されます。私はviモードを好み、他の人はemacsモードを好みます。
他のすべての人にviモードを使用させることなく、任意のマシンへのSSHログイン時にbashのreadlineを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 command
を実行すると、command
が実行されますが、(.bashrc
はソースされないため).yourname
ファイルが残るため、疑似プロキシを使用しないssh設定の2番目のエイリアス。実際、のみこのアプローチの利点は、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
構成に疑似プロキシを呼び出さない2番目のエイリアスが必要になります。
私は行きます:
ssh server -t "bash --login -o vi"
しかし、あなたが管理者であれば、もっとクリーンなものを試すことができます。たとえば、クライアント側でssh SendEnv
オプションを使用して特定の変数を送信し、AcceptEnv
構成(サーバー側)でsshd
を使用してそれを受け入れ、ベースにすることができます。これについては、rootの.bashrc
ファイルを変更して、変数の値に応じて動作を調整します。
これは、すべてのホストのsshd
構成とその.bashrc
を変更することを意味します。ただし、正確には「スタンドアロン」の方法ではありません...
簡単なクライアント側ソリューションの場合:
alias connect='ssh -t root@server "bash -o vi"'
ルートのシェル初期化スクリプトが明示的にset -o emacs
を使用するか、EDITOR
をemacs
に設定する場合、またはルートの.initrc
ファイルがemacs
キーバインディングを呼び出す場合、これは失敗します。 。
この回答の残りの部分は、サーバー側のソリューションに関するものです。
これは、マシンにssh
-してから、Sudo -i
を使用する場合に機能します。
あなたの/root/.bashrc
の場合:
if [[ -n "$Sudo_USER" ]] && [[ -f /root/.bashrc-"$Sudo_USER" ]]; then
source /root/.bashrc-"$Sudo_USER"
fi
これにより、/root/.bashrc-patrick
と呼ばれる個人のbashrc
ファイルを作成できます。このファイルでは、set -o vi
などの好きなことを実行できます。
これを、$SSH_CLIENT
に応じてそのrcファイルを取得するためのやや素朴なアプローチと組み合わせる:
if [[ -n "$Sudo_USER" ]]; then
person="$Sudo_USER"
Elif [[ -n "$SSH_CLIENT" ]]; then
case "$SSH_CLIENT" in
192.168.216.100*) person="joe" ;;
192.168.216.120*) person="patrick" ;;
192.168.216.150*) person="lindsey" ;;
esac
fi
if [[ -n "$person" ]] && [[ -f /root/.bashrc-"$person" ]]; then
source /root/.bashrc-"$person"
fi
これは明らかに、常に同じIPアドレスから接続している場合にのみ機能します...
使用している特定のSSHキーのコメントフィールドを使用する別のアプローチ。これは、SSHエージェントをサーバーに転送する場合に機能します。
ssh_comment="$( ssh-add -L | grep -f /root/.ssh/authorized_keys | awk '{ print $NF '} | head -n 1 )"
これにより、サーバーへの接続に使用したキーのコメントフィールドが選択されます。 head -n 1
ファイルにいくつかのキーがある場合に備えて、authorized_keys
があります。
次に、上記の$ssh_comment
アプローチ(パス名の場合は$Sudo_USER
のコメントをクリーンアップする必要がある場合があります)の場合と同様に、$ssh_comment
を使用してソースとするrcファイルを選択できます。 )、または$SSH_CLIENT
アプローチと同様にcase
ステートメントを介して。
サーバー側で変更せずに本当に実行したい場合は、次のいずれかを実行します。
1)次のようなものを実行します
$ ssh user@Host -t 'bash -l -o vi'
documentation はあまり明確ではないと思いますが、-o option
が言及されており、機能しているようです。
2)expectを使用します。
expect
スクリプト:
$ cat bashsetup.expect
#!/usr/bin/expect -f
set user [lindex $argv 0];
set Host [lindex $argv 1];
spawn ssh -l $user $Host
expect "$ "
send "set -o vi\n"
interact
実行可能にして実行します。
$ ./bashsetup.expect user testhost
spawn ssh -l user testhost
[motd, blahblah...]
user@testhost ~$ set -o vi
user@testhost ~$
これは、(リモートホストまたはキーの)パスワードを入力せずにログインできることを前提としています。そうでない場合、expectスクリプトはそれを考慮する必要があります。しかし、多くのマシンでは、すでにそれを持っている可能性があります。また、ドル記号とスペースがexpectedである場合は、プロンプトに従って編集します:"# "
おそらく。
プロンプトの前に印刷されたものに同じ文字が含まれている場合でも、予想される文字列にさらに具体的なものを含める必要があります。
また、そのスクリプトはssh
への追加の引数の指定をサポートしていません。実行する明示的なコマンドを指定する場合は、おそらくviモードは必要ありませんが、ポートトンネリングなどが必要な場合は、問題になる可能性があります。
しかし、いずれにせよ、これは個別のアカウント(Sudo
または単なる古いUID0)を持つターゲットシステムで解決する必要があると本当に思います。パーソナライズされた構成は、他の多くの場合にも役立ちます。一般に、設定したい構成ファイルと環境変数がたくさんあります。 (管理者が$EDITOR
の値、またはvirc
の内容などに同意しない可能性があることを考慮してください。)
また、個別のアカウントを使用すると、ユーザーの削除が簡単になります。
すべてのホストでファイルを同期する方法でも、ssh -t user@Host 'patricks_Shell.sh'
やssh -t user@Host 'bash --rcfile patrick.rc'
のようなものでログインできるようにすることで、これを簡単に解決できます。
SSH config auto execute remote command | Unix&Linux Stack Exchange