web-dev-qa-db-ja.com

インタラクティブに使用する場合にのみ、ssh LocalCommandにGNU-screenウィンドウのタイトルを設定させますか?

セットアップ

ローカルマシンでscreenを実行し、さまざまな画面ウィンドウを使用してさまざまなホストに接続します。 sshプロセス中にウィンドウ名をホスト名に自動的に変更すると便利です。

アプローチ

以下の2つのアプローチのさまざまなバリエーションを試しました。

1)ssh設定ファイルでLocalComandを使用する:

_Host *
PermitLocalCommand yes
LocalCommand '[ "${TERM:0:6}" == "screen" ] && printf "\ek@%h\e\\"
_

2)カスタムbash関数の作成:

_# function to set screen name based on Host and reset on exit
function ssh() {
  echo -e '\033k'@$1'\033\\'
  ssh -Y "$@"
  echo -e '\033k'local'\033\\'
}
_

問題

これらのアプローチはどちらも機能しますが、オートコンプリートなどにも干渉するようです。

_$ scp user@Host:~/.s<tab>
...o^[\\\\   ...cal^[\\\\
_

質問

ホストに接続しているときだけLocalCommand(またはssh()関数)を実行できるようにする(_$TERM == screen_かどうかのチェックに加えて)使用できる条件はありますか?オートコンプリートに使用する場合は?

これらの制御シーケンスを印刷する必要があるため、screenがそれらをキャプチャします。それでも、それらをsshの標準出力に出力してはなりません。 stderrに出力します。sshを使用する完了関数は、出力のみをキャプチャして使用する必要があり、エラーメッセージを無視する必要があります。ただし、通常sshを使用すると、screensshからstdoutとsterrを取得します。

関数が変更されました:

# function to set screen name based on Host and reset on exit
function ssh() {
  echo -e '\033k'@$1'\033\\' >&2
  command ssh -Y "$@"
  echo -e '\033k'local'\033\\' >&2
}

単語commandを追加したことに注意してください。これがないと、関数はそれ自体を再帰的に呼び出します。

上記の関数は、$1がホスト名などであることに依存しています。一般的にはそうではないかもしれません。より堅牢な解決策は、LocalCommandとその%hを使用して一方向に変更してから、関数を使用してlocalに戻すことです。

Host *
PermitLocalCommand yes
LocalCommand exec bash -c '[ "${TERM:0:6}" == "screen" ] && printf "\ek@%h\e\\" >&2' ssh-bash

${TERM:0:6}は移植性がないため、bashにコマンドの処理を強制しました。 LocalCommandは、一般に構文をサポートしない可能性のあるユーザーのシェルを使用します。

# function to reset screen name on exit
function ssh() {
  command ssh "$@"
  echo -ne '\033klocal\033\\' >&2
}

関数から-Yを削除しました。これで、必要に応じて引数として提供しても安全です。

Stderrへの印刷が他の何かに干渉する場合は、/dev/ttyprintf … >/dev/tty)に直接印刷することを検討してください。ただし、これには独自の微妙な点があります。

1