Получение ширины консоли с помощью 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есть и , например &pts/terminalnumber/dev/pts/terminalnumberpts/0/dev/pts/0


1
unix.stackexchange.com/questions/16578/… может помочь вам.
PhK

@ phk Не думаю, что это помогает. Вопрос в том, как сообщить драйверу tty фактических значений для столбцов / строк. Вот это, чтобы определить их из tty драйвера.
Ройма

Я не думал, что у cronрабочих мест были контрольные терминалы.
TMN

Ответы:


18

Команда tputявляется отличным инструментом, но, к сожалению, она не может получить фактические настройки для произвольно выбранного терминала.

Причина этого в том, что он читает стандартный вывод для характеристик терминала, и это также то, где он пишет свой ответ. Таким образом, в момент, когда вы пытаетесь захватить вывод, tput colsвы также удалили источник его информации.

К счастью, sttyчитает stdin, а не stdout для определения характеристик терминала, поэтому вы можете получить необходимую информацию о размере:

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? Мой (ncurses 6.0.20160625) делает TIOCGWINSZ на stderr, если он не может сделать это на stdout. cols=$(tput cols)или cols=$(tput cols 2<> /dev/ttyx) работает просто отлично.
Стефан Шазелас

@ StéphaneChazelas У меня 5.9 + 20140913-1 + b1, изначально установленный из Debian "sid". Просто ищу новую версию сейчас.
Ройма

1
Работает также и ncurses 5.7.20100313здесь. Вы уверены, cols=$(tput cols 2<> /dev/tty1)что не работает для вас?
Стефан Шазелас

@ StéphaneChazelas увлекательно. Вы правы: если я перееду стандартный вывод от терминала, tput colsэто читать STDERR . Теперь мне нужно решить, как переписать мой ответ ...
Ройма

1
Я бы использовал stty size <"$terminal" | read rows columnsвместо того, чтобы пытаться разобратьstty -a
Random832

13

tput colsи tput linesзапросить размер терминала (из драйвера терминального устройства, а не самого терминала) у терминального устройства на его stdout, и, если stdout не является терминальным устройством, как в случае, cols=$(tput cols)где это тогда канал, из stderr.

Таким образом, чтобы извлечь значения из произвольного оконечного устройства, вам нужно открыть это устройство в строке tput:

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

(здесь открывается в режиме только для чтения, поэтому tputтам не выводятся сообщения об ошибках).

Кроме того, вы можете использовать stty size. sttyзапрашивает терминал на stdin:

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

Ни один из них не является стандартным, поэтому может (и на практике не будет) работать на всех системах. Он должен быть достаточно переносимым для систем GNU / Linux.

В stty sizePOSIX было запрошено добавление или другой метод для запроса размера терминала, но обсуждение, похоже, никуда не денется.


8

Этот скрипт:

#!/bin/bash

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

Работал здесь абсолютно ничего больше .....

Почему вы устанавливаете переменную среды с данными? COLUMNS = $ (/ дома / испытания / Документы / get_columns.sh)

Вы пытаетесь получить столбцы и строки из другого скрипта или tty? Это оно? Все еще странно для меня, потому что вы устанавливаете переменную окружения столбцов для локального сценария ....


Это не помогает получить значения в работе OP cronдля конкретного терминала.
Ройма

1
Ahn? Какая? Теперь я более запутался, как скрипты cronjobs могут иметь ширину ????? Они на самом деле не работают в терминале.
Лучано Андресс Мартини

Я знаю. cronРабота запрашивает конкретный терминал для его характеристик. (Я не совсем уверен, почему он должен это делать, но это то, чего хочет ОП.)
Ройма

@LucianoAndressMartini $ COLUMNS и $ LINES являются переменными bash, они не работают (например, в dash и posh
ingroxd

Tks. Я действительно знаю, но мой сценарий - hashbang с / bin / bash, я думаю, что вы должны знать, что вы должны его использовать. Если вы используете Unix без Bash, возможно, мой ответ не для вас.
Лучано Андресс Мартини,

1

Мой ответ отличается от ответа Роймы, так как он динамичен. Его / Hers ответ дает вам размер терминала при создании. Если вы, например, используете менеджер окон, например i3 или bspwm, вы бы предпочли иметь текущую ширину терминала. Поэтому я использую ssty из пакета coreutils:

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

Решение Лучано работает безупречно в xterm и xfce4-терминал. Я не знаю, все ли терминалы устанавливают переменную $ COLUMNS.


Это не более динамично, чем мой ответ. Оба дают вам размер терминала в тот момент, когда вы запускаете команды.
Роайма
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.