サイズ変更可能なシリアルコンソールウィンドウ?


25

私のシステムのシリアルコンソールを使用するとき、私は常にとに$COLUMNS=80なり$LINES=24ます。

これらの変数は手動で変更できますが、クライアント側のターミナルウィンドウのサイズが変更されたときにいつでも変更するのは面倒です。

通常、を使用してコンソールに接続していscreen /dev/mytty baudrateます。

変更$TERM「画面」または「のxterm」に、環境変数は助けにはなりません。

gettyvt100の代わりにそれらのいくつかを呼び出す必要がありますか?

言うまでもなく、sshを使用して同じマシンに接続すると、このすべてが正常に機能します。

回答:


26

前に述べたコメンテーターのように、resizeすべてのコマンドの後に呼び出すことに代わるものはありません。このコマンドがなく、パッケージを(xterm)にインストールしたくない場合、ここに同じことを行う2つのPOSIXシェルスクリプトがあります。 ANSIターミナルエスケープコードの使用:

res() {

  old=$(stty -g)
  stty raw -echo min 0 time 5

  printf '\0337\033[r\033[999;999H\033[6n\0338' > /dev/tty
  IFS='[;R' read -r _ rows cols _ < /dev/tty

  stty "$old"

  # echo "cols:$cols"
  # echo "rows:$rows"
  stty cols "$cols" rows "$rows"
}

res2() {

  old=$(stty -g)
  stty raw -echo min 0 time 5

  printf '\033[18t' > /dev/tty
  IFS=';t' read -r _ rows cols _ < /dev/tty

  stty "$old"

  # echo "cols:$cols"
  # echo "rows:$rows"
  stty cols "$cols" rows "$rows"
}

ところで、私の.profileファイルには次の [ $(tty) = /dev/ttyS0 ] && res ものがあります。たとえば、デバイスを再起動した後など、シリアルライン(管理に使用するもの)を介したログインごとに端末サイズが決定されます。
また、コメント内のrsawによるアイデアも参照してください。[ $(tty) = /dev/ttyS0 ] && trap res2 DEBUG代わりに行があり、すべてのコマンドの後にサイズ変更が実行されます(ただし、必ずしもそうではない、または常に可能ではないことに注意してくださいbusybox)。


3
PS:、より永続的に追加するには[[ $(tty) == /dev/ttyS0 ]] && trap res2 DEBUG、シェルプロファイルのconfigsのいずれかに(例えば、/etc/profile~/.bash_profile)。これにより、すべてのコマンドの後に実行されます(screen / tmux / terminal-emulatorを使用してウィンドウ/ペインのサイズを変更する場合にのみ有効です)。
rsaw 16

2
数分間それを使用した後、私はすぐに、両方がresres2が最初のログインで使用する以外には遅すぎることに気付きました。私のマシンでは、両方とも0.5秒かかって終了します...すべてのコマンドが遅いように見えます(DEBUGトラップで使用した場合)。おっと!それはできません。私がインストールするだろうと思いますxterm
rsaw 16

3
@phk xtermの方resizeが高速です(通常0.002秒)。
rsaw 16

1
@rsawああ、知っておくといい、私はそれが同様に振る舞うので、同様に遅いと思った いくつかのbusyboxes の1つが私にとって同じくらい遅いように思われたことを覚えています。
phk 16

1
このスタンドアロンソリューションをありがとう。x11またはxtermがインストールされていないコンソール専用ディストリビューションを使用しているためresize、オプションではありません。
thom_nic

16

記録のために、ここにこの問題に対する答えがあります(Usenetが勝ちました):

サイズ変更操作が行われた後、仮想端末アプリケーション(xtermrxvtおよび友人)内で実行されているコンソールアプリケーションが受信SIGWINCHされます。したがって、アプリケーションは、対応するシグナルハンドラでウィンドウなどを再描画できます。

残念ながら、シリアルコンソールを使用する場合、そのようなメカニズムはありません。

ただし、アプリケーションが現在のコンソールウィンドウサイズを積極的に要求することは可能です。2番目に良いことは、コマンドプロンプトがシェルによって出力されるたびにこれを行うことです。

これは、最初に特別なサイズ変更実行可能ファイルコンパイルし、次に以下を使用して実現できますbashrc

if [ $(tty) == '/dev/ttyS0' ]; then
  trap resize DEBUG
fi

もちろん、これにより、実行時にコンソールアプリケーションのコンソールサイズの設定が変更されることはありません。


1
それ、シリアル回線上のプロトコルを実行することは可能であるべきではないすべての機能を提供しますか?クライアントとサーバーがあります。インバンドエスケープシーケンスを使用してほぼすべてを実行でき、プレーンテキストシリアルコンソールで動作します。
Evi1M4chine 16

1
実際、コード内のコメントによりresize、システムにインストールされているバージョンではないことがわかります。
トーマスディッキー

9

例えば、「サイズ変更可能」端子は、(NAWSの結果であるNegotiate About Window Sizeから、RFC 1073 のTelnetウィンドウサイズオプション)。

シリアルポートを使用してコンピューターに直接接続している場合、ネゴシエーションは関係なく、コンピューターは端末の画面サイズを直接認識しません。

端末がサイズをネゴシエートできる場合、コンピューターはSIGWINCH端末で実行されているアプリケーションに送信し、画面サイズの概念を更新するように伝えます。

コンピューターが画面サイズを知らない場合、通常はstty -a(行と列)で表示されるサイズをゼロに設定します。インタラクティブに使用する場合、これはやや不親切であり、一部のシステムは環境変数LINESを使用しCOLUMNSて支援します。割り当てられた値は、端末の説明から取得できます。多くの場合、単純にハードコーディングされています。これらの変数の規則では、たとえばcursesアプリケーションのuse_env機能で明示的に抑制されない限り、それらが有効になることが必要です。プラス面として、これらの変数は信頼できる情報が利用できない場合に役立ちます。マイナス面では、これらの変数を変更する便利な方法はありません。

resizeプログラム(を備えたユーティリティはxterm)画面サイズを決定するためのVT100スタイルのカーソル位置報告エスケープシーケンスを使用することができます。これはコマンドラインから実行できます。(再び)自動的に行う便利な方法はありません。副作用として、resizeが表示する行/列の情報を更新しますstty。更新された環境変数を提供するためのその使用はこのような場合のために、主に有用であるLINESとはCOLUMNS されている設定、および更新する必要があります。


3

私の組み込みLinuxシステム(Angstromを実行しているOvero)でうまく機能した別のソリューションを次に示します。.bashrcファイルから実行しました。Xパッケージをインストールする必要があるため、サイズ変更を使用したくありませんでした。

端末が24行を超えることをRaspberry Piに伝える| 浅い思考のブログ


3
ただリンクを投稿しないでください:情報はここにも利用可能であるように、関連する詳細が含まれ...
jasonwryan

1
残念なことに、Pythonが必要です。
クレイグマックイーン14年


1

シリアル回線を介してシェルセッションを実行する場合resize、接続を確立した後、各端末のジオメトリが変更された後、そのセッション内でコマンドを呼び出すだけで十分です。

このresizeコマンドはxtermの一部ですが、X11に依存しません。たとえば、Fedoraでは、として個別にパッケージ化されていxterm-resizeます。

動作方法:resizeコマンドは、カーソルの動きを介して高さ/幅を測定し、エスケープシーケンスを介してそれらの値を端末に送信します。

zshのようなシェルを使用すると、これも自動的にLINESand COLUMNS変数を更新します(あるいは、コマンドがstdoutに出力するexportステートメントを評価できます)。

これが必要な理由:ローカルまたはsshセッションでは、端末はジオメトリの変更についてセッションにシグナルを送ることができます(SIGWINCHを参照)。このメカニズムは、シリアル接続では機能しません。


0

bashでのみ機能するシンプルで高速なサイズ変更関数を次に示します。これは、phkのres2から変更されており、bashを使用しread -d delimて、タイムアウトによる読み取り終了を回避します。

resize() {
  old=$(stty -g)
  stty -echo
  printf '\033[18t'
  IFS=';' read -d t _ rows cols _
  stty "$old"
  stty cols "$cols" rows "$rows"
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.