Dav*_*ide 62 bash shell terminal environment-variables
考虑以下:
me@mine:~$ cat a.sh
#!/bin/bash
echo "Lines: " $LINES
echo "Columns: " $COLUMNS
me@mine:~$ ./a.sh
Lines:
Columns:
me@mine:~$ echo "Lines: " $LINES
Lines: 52
me@mine:~$ echo "Columns: " $COLUMNS
Columns: 157
me@mine:~$
Run Code Online (Sandbox Code Playgroud)
变量$LINES
和$COLUMNS
是shell变量,不是环境变量,因而不会被导出到子进程(但会被自动更新,当我调整xterm窗口,通过SSH从远程位置登录,即使).有没有办法让我的脚本知道当前的终端大小?
编辑:我需要这个作为解决方法来解决这个问题:vi(以及vim,less和类似的命令)每次使用它时都会搞砸屏幕.更改终端不是一个选项,因此我正在寻找解决方法(向下滚动$LINES
线肯定不是完美的解决方案,但至少比丢失前一个屏幕更好)
Pup*_*ppe 80
您可以从tput
以下位置获取行和列:
#!/bin/bash
lines=$(tput lines)
columns=$(tput cols)
echo "Lines: " $lines
echo "Columns: " $columns
Run Code Online (Sandbox Code Playgroud)
Cy *_*nol 23
因为这个问题很受欢迎,我想添加一个更新的答案,其中包含一些额外的信息.
通常,在现代系统中,$COLUMNS
和$LINES
变量不是环境变量.shell在每个命令之后动态设置这些值,我们通常无法从非交互式脚本访问它们.如果我们导出它们,某些程序会尊重这些值,但这种行为不是标准化的或普遍支持的.
当我们使用以下选项启用选项时,Bash将这些变量设置在流程范围内(而不是环境)checkwinsize
:
shopt -s checkwinsize
Run Code Online (Sandbox Code Playgroud)
许多系统在默认或系统范围的启动文件(/ etc/bashrc或类似版本)中为我们启用此选项,因此我们需要记住这些变量可能并不总是可用.在某些系统上,例如Cygwin,我们没有启用此选项,因此Bash不会设置$COLUMNS
,$LINES
除非我们执行上面的行或将其添加到〜/ .bashrc中.
当写非交互式脚本,我们通常不希望依赖于$LINES
和$COLUMNS
默认情况下(但我们可以检查这些允许如果需要,用户可以手动覆盖终端大小).
相反,stty
和tput
实用程序提供了从脚本中确定终端大小的可移植方法(下面描述的命令目前正在进行POSIX的标准化).
如Puppe接受的答案所示,我们可以用tput
非常简单的方式收集终端大小:
lines=$(tput lines)
columns=$(tput cols)
Run Code Online (Sandbox Code Playgroud)
或者,size
查询为stty
我们提供一步中的终端行和列的数量(输出为行数,后跟两个空格,后跟列数):
size=$(stty size) # "40 80" for example
Run Code Online (Sandbox Code Playgroud)
该stty
程序通常附带GNU Coreutils,因此我们经常可以在没有它的系统上找到它tput
.我有时更喜欢这种stty
方法,因为我们调用一个较少的命令和子shell(在Cygwin上很昂贵),但它确实要求我们将输出解析为行和列,这可能不太可读:
lines=${size% *}
columns=${size#* }
Run Code Online (Sandbox Code Playgroud)
上述两种方法都适用于任何POSIX shell.特别是对于Bash,我们可以使用进程替换来简化前面的示例:
read lines columns < <(stty size)
Run Code Online (Sandbox Code Playgroud)
...运行速度比tput
示例快,但仍然比第一次stty
执行慢,至少在我的机器上.在实践中,性能影响可能是微不足道的 - 选择最适合程序的方法(或基于目标系统上可用的命令).
如果出于某种原因,我们仍然希望在脚本中使用checkwinsize
和$LINES
,我们可以配置Bash将这些变量导出到环境中:
#!/bin/bash
shopt -s checkwinsize
cat /dev/null # Refresh LINES and COLUMNS
Run Code Online (Sandbox Code Playgroud)
Bash $COLUMNS
陷阱在提示符处输入的每个命令之前执行,因此我们可以使用它来导出这些变量.通过使用每个命令重新导出它们,我们确保在终端大小更改时环境变量保持最新.将此行添加到.bashrc以及$LINES
上面显示的选项.它适用于个人脚本,但我不建议在任何将共享的脚本中使用这些变量.
小智 6
为了完成起见,让我提一下,设置 'checkwinsize' 选项正是 OP 正在寻找的,但有一个问题。默认情况下,它在非交互式脚本中是未设置的,但您可以选择在任何脚本的开头添加以下行以启用它:
shopt -s checkwinsize
Run Code Online (Sandbox Code Playgroud)
不幸的是,LINES 和 COLUMNS 变量在设置选项时不会立即设置(至少在我最后一次尝试时)。相反,您需要强制 Bash 等待子 shell 完成,此时它将设置这些变量。因此,此问题的完整 Bash 解决方案是使用以下行启动您的脚本:
shopt -s checkwinsize; (:;:)
Run Code Online (Sandbox Code Playgroud)
然后,您可以根据自己的喜好使用 LINES 和 COLUMNS 变量,每次调整终端大小时,它们都会重置为正确的值,而无需调用任何外部实用程序。
小智 5
跑步help export
可能有帮助吗?
me@mine:~$ cat a.sh
#!/bin/bash
echo "Lines: " $LINES
echo "Columns: " $COLUMNS
me@mine:~$ ./a.sh
Lines:
Columns:
me@mine:~$ echo "Lines: " $LINES
Lines: 52
me@mine:~$ echo "Columns: " $COLUMNS
Columns: 157
me@mine:~$ export LINES COLUMNS
me@mine:~$ ./a.sh
Lines: 52
Columns: 157
me@mine:~$
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
38657 次 |
最近记录: |