bash 스크립트를 사용하여 콘솔 너비 얻기


15

스크립트를 사용하여 터미널 크기를 얻는 데 문제가 있습니다. 일반적으로 tput cols콘솔 내 에서 명령을 사용 하지만 스크립트를 엄격하게 사용하여이 기능을 수행 할 수 있기를 원합니다.

현재 실행중인 콘솔을 감지하고 파일 경로를 얻을 수 있습니다. 그러나 나는이 정보를 사용하여 콘솔의 너비를 얻는 데 어려움을 겪고 있습니다. 나는 명령을 사용하려고 시도했지만 tputLinux / 스크립트를 처음 접했기 때문에 실제로 무엇을 해야할지 모릅니다.

이렇게하는 이유 는 콘솔에 너비 / 열을 자주 알리는 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 드라이버에서 확인합니다.
— roaima

나는 cron직업이 터미널을 통제 한다고 생각하지 않았다 .
— TMN

답변:


18

이 tput명령은 훌륭한 도구이지만 불행히도 임의로 선택한 터미널의 실제 설정을 검색 할 수 없습니다.

그 이유 는 터미널 특성에 대한 표준 출력 을 읽으며 응답을 쓰는 곳이기도합니다. 따라서 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? 광산 (6.0.20160625)은 stdout에서 수행 할 수없는 경우 stderr에서 TIOCGWINSZ를 수행합니다. cols=$(tput cols)또는 cols=$(tput cols 2<> /dev/ttyx) 잘 작동합니다.
— Stéphane Chazelas

@ StéphaneChazelas 데비안 "sid"에서 5.9 + 20140913-1 + b1을 설치했습니다. 최신 버전을 찾고 있습니다.
— roaima

1
ncurses 5.7.20100313여기 에서도 잘 작동 합니다. 당신은 긍정적 cols=$(tput cols 2<> /dev/tty1)이지 않습니까?
— Stéphane Chazelas

@ StéphaneChazelas 매혹적인. 맞습니다 : stdout을 터미널에서 멀리 이동하면 stderrtput cols 에서 읽습니다 . 이제 답변을 다시 작성하는 방법을
— 알아봐야합니다

1
stty size <"$terminal" | read rows columns파싱 하는 대신에 사용하고 싶습니다stty -a
— Random832

13

tput cols 과 tput lines 쿼리를 상기 단말 장치로부터의 표준 출력에 (그 자체 단말 단말 장치 드라이버로부터의) 단말기의 크기, 만약 표준 출력은의 경우와 같은 단말 장치가 아닌 cols=$(tput cols)가 열려진에서 다음 파이프 어디.

따라서 임의의 터미널 장치에서 값을 검색하려면 stderr에서 해당 장치를 열어야합니다 tput.

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

(여기서는 읽기 전용 모드로 열리므로 tput오류 메시지가 출력되지 않습니다).

또는을 사용할 수도 있습니다 stty size. sttystdin에서 터미널을 쿼리합니다.

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

이들 중 어느 것도 표준이 아니므로 모든 시스템에서 작동하지 않을 수도 있습니다 (실제로는 작동하지 않을 수도 있음). 그래도 GNU / Linux 시스템에 이식성이 뛰어나야합니다.

stty sizePOSIX에 터미널 크기를 쿼리 하는 추가 또는 다른 방법이 요청 되었지만 토론이 진행되지 않는 것 같습니다.


9

이 스크립트는 :

#!/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 작업 내의 값을 검색하는 데 도움이되지 않습니다 .
— roaima

1
안? 뭐? 이제 더 혼란 스럽습니다 .cronjobs 스크립트가 너비를 가질 수있는 방법은 무엇입니까 ????? 실제로 터미널에서 실행되지 않습니다.
— Luciano Andress Martini

알아. cron작업의 특성에 대한 특정 터미널을 조회합니다. (왜 그렇게해야하는지 확실하지 않지만 OP가 원하는 것입니다.)
— roaima

@LucianoAndressMartini $ 열 및 $ 라인이 대시와 포쉬에 (예를 들어) 작업을하지 않는, bash는 변수
— ingroxd

Tks. 나는 정말로 알고 있지만 내 스크립트는 / bin / bash가있는 hashbang입니다. 사용해야한다는 것을 알고 있다고 생각합니다. bash없이 유닉스를 사용한다면 내 대답은 당신을위한 것이 아닙니다.
— Luciano Andress Martini

1

내 대답은 동적이기 때문에 Roaima와 다릅니다. 그 / 그녀의 대답은 당신이 창조 할 때 터미널의 크기를 알려줍니다. 예를 들어 i3 또는 bspwm과 같은 바둑판 식 창 관리자를 사용하는 경우 터미널의 현재 너비를 원할 것입니다. 따라서 coreutils 패키지에서 ssty를 사용합니다.

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

Luciano의 솔루션은 xterm 및 xfce4 터미널에서 완벽하게 작동합니다. 모든 터미널이 $ COLUMNS 변수를 설정했는지 알 수 없습니다.


이것은 내 대답보다 더 역동적이지 않습니다. 둘 다 명령을 실행하는 시점에서 터미널 크기를 제공합니다.
— roaima
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.