使用 bash 脚本获取控制台宽度

sir*_*r21 20 terminal shell-script tput

我遇到了一个问题,我试图通过使用脚本来获取终端的大小。通常我会tput cols在控制台内使用该命令,但是我希望能够通过严格使用脚本来完成此功能。

截至目前,我能够检测到正在运行的控制台并获取其文件路径。但是,我正在努力使用此信息来获取控制台的宽度。我已经尝试使用该命令tput,但我对 Linux/脚本还很陌生,因此我真的不知道该怎么做。

这样做的原因是我希望能够设置一个cron条目,每隔一段时间通知控制台其宽度/列。

到目前为止,这是我的代码:

文件

#!/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
Run Code Online (Sandbox Code Playgroud)

get_columns.sh

#!/usr/bin/env bash
echo $(/usr/bin/tput cols)
Run Code Online (Sandbox Code Playgroud)

TERMINAL&的正常输出TERMINALPATH是and ,例如&pts/terminalnumber/dev/pts/terminalnumberpts/0/dev/pts/0

roa*_*ima 21

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+')
Run Code Online (Sandbox Code Playgroud)

顺便说一下,把它写成echo $(/usr/bin/tput cols).

对于echo $(some_command)您正在运行some_command并捕获其输出的任何构造,然后将其传递echo给输出。在几乎所有您可以想象的情况下,您还不如直接运行some_command并让它直接提供输出。它更有效,也更容易阅读。

  • 我会使用`stty size &lt;"$terminal" | 读取行列而不是尝试解析 stty -a (2认同)

Sté*_*las 16

tput colstput lines从其 stdout 上的终端设备查询终端的大小(从终端设备驱动程序,而不是终端本身),如果 stdout 不是终端设备,就像cols=$(tput cols)它是管道的情况一样,则从 stderr。

因此,要从任意终端设备检索值,您需要在以下标准错误上打开该设备tput

{ cols=$(tput cols) rows=$(tput lines); } 2< "$TERMINALPATH"
Run Code Online (Sandbox Code Playgroud)

(此处以只读模式打开,因此tput不会在此处输出错误消息)。

或者,您可以使用stty size. stty在 stdin 上查询终端:

read rows cols < <(stty size < "$TERMINALPATH")
Run Code Online (Sandbox Code Playgroud)

这些都不是标准的,因此可能(实际上不会)在所有系统上都有效。不过,它对于 GNU/Linux 系统来说应该是相当可移植的。

stty sizePOSIX 要求添加或其他方法来查询终端大小,但讨论似乎没有任何进展。


Luc*_*ini 10

这个脚本:

#!/bin/bash

echo "The number of columns are $COLUMNS"
echo "The number of lines are $LINES"
Run Code Online (Sandbox Code Playgroud)

在这里工作绝对没有更多.....

为什么要使用数据设置环境变量?

COLUMNS=$(/home/test/Documents/get_columns.sh)
Run Code Online (Sandbox Code Playgroud)

您是否尝试从其他脚本或 tty 获取列和行?是这样吗?对我来说仍然很奇怪,因为您正在为本地脚本设置列环境变量....


Sas*_*sha 5

我的答案与 Roaima 的不同,因为它是动态的。他/她的回答为您提供了创建时终端的大小。例如,如果您使用平铺窗口管理器,如 i3 或 bspwm,您更希望拥有终端的当前宽度。因此,我使用了 coreutils 包中的 ssty:

#!/bin/bash
stty size | awk '{print $2}'
Run Code Online (Sandbox Code Playgroud)

Luciano 的解决方案在 xterm 和 xfce4-terminal 中完美无缺。我不知道是否所有终端都设置了 $COLUMNS 变量。