터미널 창의 너비와 높이는 어떻게 찾습니까?


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를 일관되게 올바른 창 크기 얻기를 위해에서는 lib 생성 npmjs.com/package/window-size
jonschlinkert

답변:


562
  • tput cols 열 수를 알려줍니다.
  • tput lines 행 수를 알려줍니다.

11
echo -e "lines\ncols"|tput -S줄과 열을 모두 얻으려면 linux.about.com/library/cmd/blcmdl1_tput.htm
nickl-

4
tput터미널의 상태를 읽고, 커서와 텍스트 속성을 제어하는 ​​등 많은 명령을 가진 훌륭한 명령입니다 .
Drew Noakes

2
예를 들어 핸디 별칭 : alias dim="echo $(tput cols)x$(tput lines)",이 발생할 수 있습니다 80x50.
감독

2
이 Q & A는 아마도 유닉스 또는 수퍼 유저 SE 사이트에 속할 것입니다 .
mydoghasworms

2
@bishop 쉘이 소스 될 때 제공 한 alias 명령이 평가됩니다. alias 명령에는 작은 따옴표를 사용해야합니다. 그래서 같이 : alias dim='echo Terminal Dimensions: $(tput cols) columns x $(tput lines) rows'
brandonsimpkins

103

배쉬에서 $LINES$COLUMNS환경 변수 트릭을 할 수 있어야합니다. 터미널 크기가 변경되면 자동으로 설정됩니다. (즉, SIGWINCH 신호)


18
그러나 이러한 환경 변수는 bash에서만 사용할 수 있으며 bash 내에서 실행되는 프로그램 (perl, python, ruby)에서는 사용할 수 없습니다.
Br.Bill

9
대화식 bash 세션 외에는 작동하지 않습니다 (스크립트를 실행하면 더 이상 대화식이 아닙니다). 스크립트에서 사용할 수있는 유일한 곳은 bash의 prompt_command입니다.
Doncho Gunchev

1
실제로 checkwinsize옵션 을 설정하면 비 대화식 스크립트에서 작동합니다 . 예를 들어,이 비 대화식 스크립트는 실행되는 터미널의 크기를 인쇄합니다. shopt -s checkwinsize; (:); echo $LINES $COLUMNS( checkwinsize옵션은 서브 쉘이 완료되기를 기다린 후에 만 ​​변수를 초기화하므로 (:)명령문이 필요합니다 )
user3340662

$LINES그리고 $COLUMNS이후에 업데이트됩니다 SIGWINCH실제로 대화 형 명령 실행 후, 전송됩니다. PS1와 업데이트를 시도 trap SIGWINCH하면 $LINESand를 사용할 수 없으며 $COLUMNS이전 값을 유지합니다 ((
gavenkoa

LINESCOLUMNS전용으로 설정되어 쉘 변수 떠들썩한 파티에 의해. 이 셸 변수를 내 보내지 않으면 Bash는 환경 변수 로 설정하지 않습니다 .
Markus Kuhn

67

그리고 거기 stty에서, 로 coreutils

$ stty size
60 120 # <= sample output

행과 열의 수 또는 높이와 너비를 각각 인쇄합니다.

그럼 당신은 사용할 수 있습니다 cut또는 awk당신이 원하는 부분을 추출 할 수 있습니다.

그것은 stty size | cut -d" " -f1높이 / 라인과 stty size | cut -d" " -f2너비 / 열을위한 것입니다.


이 스타일은 PIPE와 함께 사용할 수 없습니다. tput 스타일 사용을 제안하십시오.
liuyang1

6
tput의 문제점은 모든 tty에서 stty를 사용할 수 있지만 항상 사용할 수는 없다는 것입니다. 그 정보 주셔서 감사합니다!
iRaS

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

3
질문에 대한 직접적인 대답은 아니지만 훌륭한 데모 스크립트입니다.
Chris 페이지

좋은 예입니다!
커트 종

1
tr몇 년 동안 내가 명령을 어떻게 그리워 했 습니까? (facepalm)
Marco Massenzio

이것이 무슨 언어 지? 구문 오류가있는 쉘 스크립트와 모호하게 보입니다. (쉘에서 당신은 할당과 같은 공백을 가질 수 없으며, 첫 번째 파이프는 제자리를 벗어난 것처럼 보입니다.)
tripleee

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.columns얼랭 : io:columns(). erlang.org/doc/man/io.html#columns-0
Henrik N

2
아무 없다 TIOCGWINSZ는 POSIX 표준과 ioctl()쓸모가 기능을 스트림에서만 정의된다.
osvein

4

내가 lyceus answer에서 언급했듯이, 영어가 아닌 로케일 Windows에서는 그의 출력에 mode하위 문자열 "columns"또는 "lines"가 포함되지 않을 수 있기 때문에 코드가 실패합니다 .

                                         모드 명령 출력

텍스트를 찾지 않고 올바른 하위 문자열을 찾을 수 있습니다.

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

신뢰할 수 없기 때문에 줄을 귀찮게하지 않습니다 (실제로 신경 쓰지 않습니다).

편집하다: Windows 8 (oh you ...)에 대한 의견에 따르면 이것이 더 신뢰할 수 있다고 생각합니다.

 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);입니다. 그런 다음 숫자 이외의 모든 것을 바꿉니다.
Aleksandr Makov

@AleksandrMakov 다음과 같은 순서로 언어가 있다면 어떻게 될지 궁금합니다 CON device status:. 어쩌면 비슷한 CON.*:것을 일치시키는 것이 더 좋을 것입니다.
Camilo Martin

1
@ Mark 실제로 그 사실을 스스로에게 묻고있었습니다. 도대체 내가 왜 그랬어? 의심의 여지없이, 나는 방금 어떤 이유가 있다고 가정하고 그와 함께갔습니다.
Camilo Martin

1

@pixelbeat의 답변에서 영감을 얻은 패딩 / 채우기 tput의 약간의 오용 printftr

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.