Obtendo largura do console usando um script bash

14

Estou encontrando um problema em que estou tentando obter o tamanho de um terminal usando scripts. Normalmente eu usaria o comando tput cols dentro do console, no entanto, eu quero ser capaz de realizar esse recurso usando scripts estritamente.

A partir de agora, sou capaz de detectar o console em execução e obter seu caminho de arquivo. No entanto, estou lutando para usar essas informações para obter a largura do console. Eu tentei usar o comando tput , mas sou relativamente novo no Linux / scripts, então não sei o que fazer.

A razão para fazer isso é que eu quero ser capaz de configurar uma entrada cron que notifica o console de sua largura / colunas de tempos em tempos.

Este é o meu código até agora:

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)

A saída normal de TERMINAL & TERMINALPATH são pts/terminalnumber e /dev/pts/terminalnumber , por exemplo pts/0 & /dev/pts/0

    
por sirgeezer21 29.07.2016 / 13:42

4 respostas

15

O comando tput é uma excelente ferramenta, mas infelizmente não pode recuperar as configurações reais de um terminal selecionado arbitrariamente.

A razão para isto é que ele lê stdout para as características do terminal, e este é também onde ele escreve sua resposta. Então, no momento em que você tentar capturar a saída de tput cols , você também removeu a fonte de suas informações.

Felizmente, stty stdin em vez de stdout para determinar as características do terminal, então é assim que você pode recuperar as informações de tamanho necessárias:

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

A propósito, a construção echo $(/usr/bin/tput cols) é horrível.

Para qualquer construção echo $(some_command) , você está executando some_command e capturando sua saída, que você passa para echo para a saída. Em quase todas as situações, você pode imaginar que você poderia simplesmente executar some_command e deixá-lo entregar sua saída diretamente. É mais eficiente e também mais fácil de ler.

    
por 29.07.2016 / 15:11
12

tput cols e tput lines consultam o tamanho do terminal (do driver do dispositivo de terminal, não o próprio terminal) do dispositivo terminal em seu stdout e se stdout não é um dispositivo terminal como no caso de cols=$(tput cols) onde é então um pipe, de stderr.

Assim, para recuperar os valores de um dispositivo terminal arbitrário, você precisa abrir o dispositivo no stderr de tput :

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

(aqui aberto no modo somente leitura, então tput não exibe suas mensagens de erro)

Como alternativa, você pode usar stty size . stty consulta o terminal em stdin:

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

Nada disso é padrão, então pode (e na prática não) funcionar em todos os sistemas. Ele deve ser razoavelmente portátil para os sistemas GNU / Linux.

A adição de stty size ou outro método para consultar o tamanho do terminal foi solicitada ao POSIX , mas a discussão não parece estar indo a qualquer lugar.

    
por 29.07.2016 / 16:19
6

Este script:

#!/bin/bash

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

Trabalhei aqui com absolutamente nada mais .....

Por que você está definindo uma variável de ambiente com dados? COLUMNS = $ (/ home / test / Documents / get_columns.sh)

Você tenta obter as colunas e linhas de outro script ou tty? É isso? Ainda estranho para mim porque você está definindo a variável de ambiente de colunas para o script local ....

    
por 29.07.2016 / 13:59
0

Minha resposta é diferente da de Roaima, já que é dinâmica. A resposta dele / dela lhe dá o tamanho do terminal na criação. Se você estiver, por exemplo, usando um gerenciador de janelas lado a lado, como i3 ou bspwm, você preferiria ter a largura atual do terminal. Assim eu uso o ssty do pacote coreutils:

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

A solução de Luciano funciona sem problemas no xterm e no xfce4-terminal. Eu não sei se todos os terminais definem a variável $ COLUMNS.

    
por 19.02.2018 / 12:26