接続先ごとにプロンプトを切り替える

開発(or テスト)、ステージング、本番環境のサーバ内で作業する必要がある場合、シェルでホスト名を表示して環境を見分けていますが、どうしても限界があります.
そのため、接続先にごとにプロンプトを切り替えて、環境ごとに色を変更してみようと思います.

TL;DR

  • sshにはRemoteCommandというオプションがあり、そこにコマンドを指定すると接続時に実行してくれる
  • ssh_configにRemoteCommandRequestTTYを定義すれば接続先ごとにプロンプトを切り替えることができる

実行環境

  • ssh ... OpenSSH_7.6p1, OpenSSL 1.1.0g-fips 2 Nov 2017
  • GNU bash ... 4.4.19

接続先にごとにプロンプトを切り替える

コマンド実行時の引数に、接続した後に実行するコマンドを指定することができますが、今回はそれを利用しません.
sshにはRemoteCommandというオプションがあるので、それをssh_configに定義してからsshを実行します.

Host test-server
    HostName localhost
    Port 12345
    RequestTTY yes
    RemoteCommand PS1="\[\e[1;32m\][\u@\h \w] $\[\e[m\]" bash --login

これを利用して、development・staging・productionといった環境ごとにプロンプトを切り替えることができます.

Host development
    ...
    RequestTTY yes
    RemoteCommand RemoteCommand PS1="\[\e[1;32m\][\u@\h \w] [development]\n$ \[\e[m\]" bash --login
Host staging
    ...
    RequestTTY yes
    RemoteCommand RemoteCommand PS1="\[\e[1;33m\][\u@\h \w] [staging]\n$ \[\e[m\]" bash --login
Host production
    ...
    RequestTTY yes
    RemoteCommand RemoteCommand PS1="\[\e[1;31m\][\u@\h \w] [production]$ \[\e[m\]" bash --login

こういった定義をssh_configにしておくことで、通常のプロンプトを上書きして実行することができます.
しかし、この定義も万能ではなく上書きできないケースは存在します.

  • .bashrcにPS1が定義されている
  • /etc/bash.bashrcにPS1が定義されている

上記のケースでは上書きできないことが確認できています.
理由は、PS1を定義することで任意のプロンプトに変更していますが、
bash --login実行時に.bashrc/etc/bash.bashrcに読み込まれるため、
それらに定義されているPS1の方で上書きされてしまうためです.

では、事前に接続先にサーバー内に今回のようなPS1を定義しておけば良いでしょうか? 正直なところケースバイケースだと思っています.
私は、できる限り環境を汚したくないので、今回はこういった書き方を紹介してみました.

RequetTTYの定義は忘れずに.