web-dev-qa-db-ja.com

システムへのログイン時にbashreadlineをviモードに自動的に設定するにはどうすればよいですか?

私のチームは何千ものLinux/Unixマシンを担当しているので、当然、rootアカウントは管理者間で「共有」されます。私はviモードを好み、他の人はemacsモードを好みます。

他のすべての人にviモードを使用させることなく、任意のマシンへのSSHログイン時にbashのreadlineをviモードに設定するにはどうすればよいですか?

本質的には、ログイン後にset -o viの効果を持ちたいのですが、実際に毎回入力する必要はなく、他の人に強制することもありません(emacsモードは私にとって迷惑ですが、viモードは彼らにとって迷惑です) 。

誰もがSudoで自分のアカウントを使用して特権コマンドを実行する場合、これは問題にならないことはわかっていますが、私の制御できない状況のため、残念ながらこれはオプションではありません。

9
Patrick

これを行うためのばかげた方法は次のとおりです。これは、公開鍵認証でのみうまく機能します。

まず、ローカルマシンに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番目のエイリアスが必要になります。

3
Fox

私は行きます:

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

しかし、あなたが管理者であれば、もっとクリーンなものを試すことができます。たとえば、クライアント側でssh SendEnvオプションを使用して特定の変数を送信し、AcceptEnv構成(サーバー側)でsshdを使用してそれを受け入れ、ベースにすることができます。これについては、rootの.bashrcファイルを変更して、変数の値に応じて動作を調整します。

これは、すべてのホストのsshd構成とその.bashrcを変更することを意味します。ただし、正確には「スタンドアロン」の方法ではありません...

4
Uriel

簡単なクライアント側ソリューションの場合:

alias connect='ssh -t root@server "bash -o vi"'

ルートのシェル初期化スクリプトが明示的にset -o emacsを使用するか、EDITORemacsに設定する場合、またはルートの.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ステートメントを介して。

3
Kusalananda

サーバー側で変更せずに本当に実行したい場合は、次のいずれかを実行します。

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'のようなものでログインできるようにすることで、これを簡単に解決できます。

3
ilkkachu

このガイドに従って、カスタムrcファイルを作成できます。

ユーザーrcファイル|セキュアシェル:決定的なガイド

または、authorized_keysファイルにコマンドラインアクションを挿入します。

SSH config auto execute remote command | Unix&Linux Stack Exchange

1
temporaryuser1