ターミナルウィンドウの幅と高さを確認するにはどうすればよいですか?


295

簡単な例として=、ターミナルウィンドウの幅全体に出力できるCLIスクリプトを記述したいと思います。

#!/usr/bin/env php
<?php
echo str_repeat('=', ???);

または

#!/usr/bin/env python
print '=' * ???

または

#!/usr/bin/env bash
x=0
while [ $x -lt ??? ]; do echo -n '='; let x=$x+1 done; echo

私は一貫して正しいウィンドウサイズを取得するためにこの小さなnode.js ライブラリ
jonschlinkert

回答:


562
  • tput cols 列の数を示します。
  • tput lines 行数を示します。

11
echo -e "lines\ncols"|tput -S行と列の両方を取得するには、linux.about.com / library
cmd

4
tput端末の状態を読み取ったり、カーソルやテキストのプロパティを制御したりするためのたくさんのコマンドを備えた素晴らしいコマンドです。
ドリューノークス2014年

2
例えばハンディ別名、: alias dim="echo $(tput cols)x$(tput lines)"、になる可能性があります80x50
ビショップ

2
このQ&Aは、おそらく UNIXまたはスーパーユーザーのSEサイトに属しています。
mydoghasworms 2014

2
@bishopシェルがソース化されるときに、指定したエイリアスコマンドが評価されます。aliasコマンドには一重引用符を使用する必要があります。このように: alias dim='echo Terminal Dimensions: $(tput cols) columns x $(tput lines) rows'
ブランドンシンプキンス2018

103

bashでは、$LINESおよび$COLUMNS環境変数がそのトリックを実行できるはずです。は、端末サイズが変更されると自動的に設定されます。(つまり、SIGWINCHシグナル)


18
ただし、これらの環境変数はbashでのみ使用でき、bash内で実行されるプログラム(perl、python、rubyなど)では使用できません。
Br.Bill

9
これはインタラクティブbashセッション以外では機能しません(スクリプトを実行すると、インタラクティブではなくなります)。スクリプトで使用できる唯一の場所は、bashのprompt_commandです。
Doncho Gunchev 14

1
実際、このcheckwinsizeオプションを設定すると、非インタラクティブスクリプトで機能します。たとえば、この非対話型スクリプトは、それが実行される端末の寸法を出力します:(shopt -s checkwinsize; (:); echo $LINES $COLUMNSこのcheckwinsizeオプションは、サブシェルが完了するのを待った後でのみ変数を初期化するため、(:)ステートメントが必要です)
user3340662

$LINESそして$COLUMNS後に更新されSIGWINCH、実際に任意の対話型コマンド実行後、送信されます。あなたは更新しようとした場合PS1trap SIGWINCHは、使用することはできません$LINES$COLUMNS、彼らは古い値((キープ
gavenkoa

LINESまた、bashによってCOLUMNSのみシェル変数として設定されます。これらのシェル変数をエクスポートしない限り、Bashはそれらを環境変数として設定しません。
Markus Kuhn

67

そしてsttycoreutilsから

$ stty size
60 120 # <= sample output

行数と列数、または高さと幅をそれぞれ出力します。

次に、cutまたはawkを使用して、必要な部分を抽出できます。

それstty size | cut -d" " -f1は高さ/行とstty size | cut -d" " -f2幅/列のためのものです


このスタイルはPIPEでは機能しません。tputスタイルを使用することをお勧めします。
liuyang1 2015

6
tputの問題は、すべてのttyでsttyを使用できるのに、常に使用できるとは限らないことです。その情報をありがとう!
iRaS 2018

16
yes = | head -n$(($(tput lines) * $COLUMNS)) | tr -d '\n'

3
質問に対する直接的な回答ではなく、優れたデモスクリプトです。
クリスページ

なんて素晴らしい例でしょう!
Kurt Zhong

1
ここ何tr年もの間、命令をどのようにして逃したのですか?(facepalm)
マルコ

これは何語?構文エラーのあるシェルスクリプトのように見えます。(シェルでは、割り当ての等号の前後にスペースを入れることはできません。最初のパイプは
場違いの

2
yes '='無限の量の「=」行を出力し、次のコマンドは端末を埋めるのに十分な編成です
pixelbeat

12

Windows CLI環境でこれを行うには、modeコマンドを使用して出力を解析するのが最善の方法です。

function getTerminalSizeOnWindows() {
  $output = array();
  $size = array('width'=>0,'height'=>0);
  exec('mode',$output);
  foreach($output as $line) {
    $matches = array();
    $w = preg_match('/^\s*columns\:?\s*(\d+)\s*$/i',$line,$matches);
    if($w) {
      $size['width'] = intval($matches[1]);
    } else {
      $h = preg_match('/^\s*lines\:?\s*(\d+)\s*$/i',$line,$matches);
      if($h) {
        $size['height'] = intval($matches[1]);
      }
    }
    if($size['width'] AND $size['height']) {
      break;
    }
  }
  return $size;
}

お役に立てれば幸いです。

:返される高さはバッファ内の行数であり、ウィンドウ内に表示される行数ではありません。そこにもっと良いオプションはありますか?


3
これに関する問題に注意してください。このコマンドの出力はロケール固有です。つまり、これは別のWindowsロケールではそのままでは機能しません。これは私がWindows 7で取得するものです:i.imgur.com/Wrr7sWY.png
Camilo Martin

その解決策を含む回答を追加しました。+1!
Camilo Martin

10

POSIXでは、最終的にはTIOCGWINSZ(Get WINdow SiZe)ioctl()呼び出しを呼び出す必要があります。ほとんどの言語はそのためのラッパーのようなものを持っているべきです。たとえばPerlでは、Term :: Sizeを使用できます。

use Term::Size qw( chars );

my ( $columns, $rows ) = chars \*STDOUT;

1
これをありがとう–私を正しい方向に導いた。エリクサー::io.columnsErlang:io:columns(). erlang.org/doc/man/io.html#columns-0
Henrik N

2
TIOCGWINSZPOSIX標準にioctl()はありません。廃止されたSTREAMS機能に対してのみ定義されます。
osvein 2017年

4

lyceusの回答で述べたように、英語以外のロケールのWindowsでは彼のコードは失敗します。それは、出力にmode部分文字列「columns」または「lines」が含まれていない可能性があるためです。

                                         モードコマンド出力

あなたはテキストを探すことなく正しい部分文字列を見つけることができます:

 preg_match('/---+(\n[^|]+?){2}(?<cols>\d+)/', `mode`, $matches);
 $cols = $matches['cols'];

信頼性が低いため(そして実際には気にしないので)、私は回線についてさえ気にしていません。

編集: Windows 8についてのコメント(おやおや...)によると、これは信頼性が高いと思います。

 preg_match('/CON.*:(\n[^|]+?){3}(?<cols>\d+)/', `mode`, $matches);
 $cols = $matches['cols'];

しかし、私はテストしなかったので、テストしてみてください。


このメソッドはWin8では機能しません。複数の---行が表示されます。i.imgur.com/4x02dqT.png
mpen

@マークまあ、素晴らしい、それはただ美しいです。Windowsありがとうございます。<3(より適切なメモ:Windows 9が出たら、それを修正する方法を説明します:P)。
Camilo Martin

これが私のやり方です$mode = `mode`; list($rows, $cols) = array_slice(preg_split('/\n/', substr($mode, strpos($mode, 'CON:'))), 2, 2);。それから、数字以外はすべて置き換えます。
アレクサンドルマコフ

@AleksandrMakov次のような言語があるとどうなるのかな CON device status:どうなりますか?たぶんのようなものを一致させるCON.*:ほうがうまくいきます。
Camilo Martin

1
@マーク私は実際にその正確なことを自分に問いました。なんでそんなことをしたの?疑いはある理由があるだけだと思って、それでよかったです(笑)。
カミロマーティン

1

@ pixelbeatの答えに触発され、ここでの存在に持ち込ま水平バーだtputのわずかな誤用、printfパディング/充填はとtr

printf "%0$(tput cols)d" 0|tr '0' '='

0

行/ LINESと列が、使用されている「ターミナル」の実際のサイズと一致しない場合があります。おそらく、「tput」または「stty」が利用できない可能性があります。

これは、サイズを視覚的に確認するために使用できるbash関数です。これは140列x 80行まで機能します。必要に応じて最大値を調整できます。

function term_size
{
    local i=0 digits='' tens_fmt='' tens_args=()
    for i in {80..8}
    do
        echo $i $(( i - 2 ))
    done
    echo "If columns below wrap, LINES is first number in highest line above,"
    echo "If truncated, LINES is second number."
    for i in {1..14}
    do
        digits="${digits}1234567890"
        tens_fmt="${tens_fmt}%10d"
        tens_args=("${tens_args[@]}" $i)
    done
    printf "$tens_fmt\n" "${tens_args[@]}"
    echo "$digits"
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.