bashスクリプトを使用してコンソールの幅を取得する


15

スクリプトを使用して端末のサイズを取得しようとする問題が発生しています。通常tput cols、コンソール内でコマンドを使用しますが、スクリプトを厳密に使用してこの機能を実現できるようにしたいと考えています。

今のところ、実行中のコンソールを検出し、そのファイルパスを取得できます。ただし、この情報を使用してコンソールの幅を取得するのに苦労しています。私はコマンドを使用しようとしましたtputが、Linux /スクリプトにはかなり慣れていないので、どうすればよいかわかりません。

これを行う理由は、コンソールにその幅/列を頻繁に通知するcronエントリを設定できるようにすることです。

これはこれまでの私のコードです:

tty.sh

#!/bin/bash

#Get PID of terminal
#terminal.txt holds most recent PID of console in use
value=$(</home/test/Documents/terminal.txt)

#Get tty using the PID from terminal.txt
TERMINAL="$(ps h -p $value -o tty)"
echo $TERMINAL

#Use tty to get full filepath for terminal in use
TERMINALPATH=/dev/$TERMINAL
echo $TERMINALPATH

COLUMNS=$(/home/test/Documents/get_columns.sh)
echo $COLUMNS

get_columns.sh

#!/usr/bin/env bash
echo $(/usr/bin/tput cols)

TERMINAL&の通常の出力TERMINALPATHはand です(例:&pts/terminalnumber/dev/pts/terminalnumberpts/0/dev/pts/0


1
unix.stackexchange.com/questions/16578/…が役立つ場合があります。
phk

@phkそれは役に立たないと思います。問題は、列/行の実際の値をttyドライバーに伝える方法です。ここでは、ttyドライバーからそれらを決定します。
ロアイマ

cronジョブに制御端末があるとは思わなかった。
TMN

回答:


17

このtputコマンドは優れたツールですが、残念ながら、任意に選択された端末の実際の設定を取得することはできません。

この理由は、端末の特性についてstdoutを読み取るためであり、これはその答えを書き込む場所でもあります。したがって、出力をキャプチャしようとすると、tput colsその情報のソースも削除されます。

幸いなことに、端末の特性を判断するためにstdoutではなくstdinをstty読み取るため、これが必要なサイズ情報を取得する方法です。

terminal=/dev/pts/1
columns=$(stty -a <"$terminal" | grep -Po '(?<=columns )\d+')
rows=$(stty -a <"$terminal" | grep -Po '(?<=rows )\d+')

ちなみに、これをと書くのは不必要に面倒echo $(/usr/bin/tput cols)です。

echo $(some_command)実行中のコンストラクトsome_commandとその出力をキャプチャしてechoから、出力に渡します。ほぼすべての状況で、実行some_commandして出力を直接配信することも考えられます。より効率的で読みやすくなっています。


どちらの実装/バージョンtput/ nurses?Mine(ncurses 6.0.20160625)は、stdoutで実行できない場合、stderrでTIOCGWINSZを実行します。cols=$(tput cols)またはcols=$(tput cols 2<> /dev/ttyx) 正常に動作します。
ステファンシャゼル16

@StéphaneChazelasもともとDebian "sid"から5.9 + 20140913-1 + b1がインストールされています。今すぐ新しいバージョンを探しています。
ロアイマ

1
ncurses 5.7.20100313ここでも動作します。あなたはあなたのcols=$(tput cols 2<> /dev/tty1)ために働いていないポジティブですか?
ステファンシャゼラス16

@StéphaneChazelas魅力的です。あなただ右:私が移動した場合、標準出力離れた端末から、tput colsから読まない標準エラー出力を。私は今、私の答えを書き直す方法を
考え出す

1
stty size <"$terminal" | read rows columns解析しようとする代わりに使用しますstty -a
Random832

13

tput colstput linesstdoutの端末デバイスから端末のサイズ(端末自体ではなく端末デバイスドライバから)を照会します。stdoutがcols=$(tput cols)パイプの場合のような端末デバイスではない場合は、stderrから。

したがって、任意の端末デバイスから値を取得するには、次のstderrでそのデバイスを開く必要がありますtput

{ cols=$(tput cols) rows=$(tput lines); } 2< "$TERMINALPATH"

(ここでは読み取り専用モードで開いているためtput、エラーメッセージは出力されません)。

または、を使用できる場合がありますstty sizesttystdinで端末を照会します。

read rows cols < <(stty size < "$TERMINALPATH")

これらはどれも標準ではないため、すべてのシステムで機能しない可能性があります(実際には機能しません)。ただし、GNU / Linuxシステムにかなり移植できるはずです。

stty size端末サイズを照会するための追加またはその他の方法がPOSIXに要求されましたが、議論はどこにも行かないようです。


8

このスクリプト:

#!/bin/bash

echo "The number of columns are $COLUMNS"
echo "The number of lines are $LINES"

絶対に何もせずにここで働いた.....

環境変数にデータを設定しているのはなぜですか?COLUMNS = $(/ home / test / Documents / get_columns.sh)

他のスクリプトまたはttyから列と行を取得しようとしていますか?それですか?ローカルスクリプトの列環境変数を設定しているので、私にとってはまだ奇妙です。


これはcron、特定の端末のOPのジョブ内の値を取得するのに役立ちません。
ロアイマ

1
あん?何?今、私はもっと混乱しています、cronjobsスクリプトはどのように幅を持つことができますか?これらは実際には端末で実行されません。
ルチアーノアンドレスマティーニ

知っている。cron仕事は、その特性のために特定の端末を照会します。(なぜこれを行う必要があるのか​​は
完全にはわかり

@LucianoAndressMartini $ COLUMNSと$ LINESはbash変数であり、ダッシュや
ポッシュ

Tks。私は本当に知っていますが、私のスクリプトは/ bin / bashを使用したhashbangです。あなたはそれを使うべきだと知っているはずです。bashを使用せずにunixを使用している場合は、おそらく私の答えはあなたのためではありません。
ルチアーノアンドレスマティーニ

0

私の答えはロアイマのものとは異なります。なぜなら、それは動的だからです。彼/彼女の答えは、作成時の端末のサイズを示します。たとえば、i3やbspwmなどのタイリングウィンドウマネージャーを使用している場合は、現在の端末の幅を保持する必要があります。したがって、coreutilsパッケージのsstyを使用します。

#!/bin/bash
stty size | awk '{print $2}'

Lucianoのソリューションは、xtermおよびxfce4-terminalで問題なく動作します。すべての端末が$ COLUMNS変数を設定するかどうかはわかりません。


これは私の答えよりも動的ではありません。どちらも、コマンドを実行した時点での端末サイズを示します。
ロアイマ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.