TERM 环境变量默认在哪里设置?

And*_*iak 37 shell colors bash terminal environment-variables

当我在桌面 GUI 中使用 GNOME 终端模拟器打开终端窗口时,shell TERM 环境变量默认为值xterm

如果我使用CTL+ ALT+F1切换到控制台TTY窗口和echo $TERM的值被设定为linux

我询问的动机是在我的~/.bashrc文件中使用一个变量来确定是否提供了彩色外壳或只是老式的单色。

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color) color_prompt=yes;;
esac
Run Code Online (Sandbox Code Playgroud)

如果我键入,则在控制台外壳和 Gnome 终端仿真器外壳中

export TERM=xterm-color
source /.bashrc
Run Code Online (Sandbox Code Playgroud)

两个外壳都更改为颜色模式(我希望两者都发生)。

请在哪里TERM设置默认值,如果可能,更改默认值的最佳位置在哪里?终端仿真器 GUI 中似乎没有任何内容可以选择或设置默认的 TERM 值。

我确实考虑过将这一行添加export TERM=xterm-color到我的~/.bashrc文件顶部,但我的直觉告诉这不是最好的解决方案,而且我的 Google 搜索还没有让我得到一个好的答案。

我正在运行 Ubuntu 15.04 桌面版(基于 Debian)。

Jde*_*eBP 27

在很多地方,视情况而定

在虚拟终端和真实终端上,TERM环境变量由链接到 的程序设置login,并一直继承到登录后执行的交互式 shell。确切地说,发生这种情况的地方因系统和终端类型而异。

真实终端

真正的串行终端的类型可能会有所不同,具体取决于电线另一端的内容。因此,通常getty使用指定终端类型的参数调用程序,或者TERM从服务管理器的服务配置数据传递程序。

  • 在 van Smoorenburginit系统上,人们可以在/etc/inittab条目中看到这一点,这些条目将阅读以下内容

    S0:3:respawn:/sbin/agetty ttyS0 9600 vt100-nav
    的最后一个参数agetty在该行,vt100-nav是用于终端类型组/dev/ttyS0。所以/etc/inittab是在哪里改变终端类型用于在这样的系统真实终端。
  • 在 systemd 系统上,曾经可以在/usr/lib/systemd/system/serial-getty@.service单元文件(/lib/systemd/system/serial-getty@.service在未合并的系统上)中看到这一点,该文件用于读取

    环境=TERM=vt100
    设置环境中的TERM变量传递给agetty.
  • 在 BSD 上,init/etc/ttys数据库中每个终端条目的第三个字段中获取终端类型,并TERM根据它执行的环境中的类型getty进行设置。所以/etc/ttys是其中一个改变用于在BSD系统实际终端的终端类型。

systemd 的可变性

所述serial-getty@.service服务单元文件,或插入式适用于此的文件,是在哪里改变终端类型上systemd系统真实终端。请注意,此类更改适用于所有使用此服务单元模板的终端登录服务。(要仅为单个终端更改它,必须手动实例化模板,或添加仅适用于实例化的插件。)

systemd 在其生命周期中至少有四种机制来获取TERM环境变量的值。在第一次写这个答案时,可以看出,模板服务单元文件中有一行。在其他时候,类型和分别硬连接到和服务单元文件中。最近,环境变量是从进程#1 继承的,它以各种方式设置它。Environment=TERM=somethinglinuxvt102gettyserial-getty

截至 2020 年,systemd 决定在服务的TERM环境变量中指定哪种终端类型的方式非常复杂,并且根本没有记录。更改它的方法仍然是一个带有. 但是默认值的来源是可变的。受一些相当复杂的解释规则的约束,这些规则涉及单个服务单元的设置,它可以是三个值之一:硬连线、硬连线(不再)或进程#1 继承的环境变量的值,通常来自内核/引导加载程序。Environment=TERM=somethingTTYPath=linuxvt220vt102TERM

(具有讽刺意味的是,该getttyent()机制仍然存在于 GNU C 库中,而 systemd 可以重新使用该/etc/ttys机制。)

内核虚拟终端

正如您所指出的,内核虚拟终端具有固定类型。与 NetBSD 可以动态改变内核虚拟终端类型不同,Linux 和其他 BSD 在内核的内置终端仿真程序中实现了单一的固定终端类型。在 Linux 上,该类型与linuxterminfo 数据库中的匹配。(FreeBSD 的内核终端仿真自第 9 版以来一直是teken。在第 9 版之前,它是cons25 OpenBSD 的 is pccon。)

  • 在使用mingettyor vc-get-tty(来自 nosh 包)的系统上,程序“知道”它只能与虚拟终端对话,并且它们硬连线了适合于编译程序的操作系统的“已知”虚拟终端类型。
  • 在 systemd 系统上,过去可以在/usr/lib/systemd/system/getty@.service单元文件(/lib/systemd/system/getty@.service在未合并的系统上)中看到这一点,该文件读取

    环境=TERM=linux
    设置环境中的TERM变量传递给agetty.

对于内核虚拟终端,改变终端类型。毕竟内核中的终端模拟器程序不会改变。更改类型是错误的。特别是,这会搞乱光标/编辑键 CSI 序列识别。的linuxLinux内核终端仿真器发送CSI序列是不同的xtermvt100通过GUI终端仿真器程序在DEC VT模式发送CSI序列。(事实上​​,它们是高度特殊的和非标准的,并且与我所知道的所有真实终端以及几乎所有其他软件终端模拟器都不同,除了 Linux 中内置的那个。)

GUI终端模拟器

您的 GUI 终端模拟器是screen使用伪终端的众多程序之一,从 SSH 守护程序到。终端类型是什么取决于在伪终端的主端运行什么终端仿真程序,以及它是如何配置的。大多数 GUI 终端仿真器将使用一个TERM变量在从属端启动程序,该变量的值与其在主端的终端仿真相匹配。像 SSH 服务器这样的程序将尝试“通过”连接客户端的终端类型。通常有一些菜单或配置选项可以在终端仿真中进行选择。

紧握的手

检测颜色功能的正确方法不是在脚本中硬连接终端类型列表。有很多支持颜色的终端类型。

正确的方法是查看 termcap/terminfo 对您的终端类型的说明。

颜色=0
如果 tput Co > /dev/null 2>&1
然后
    测试 "`tput Co`" -gt 2 && colour=1
elif tput 颜色 > /dev/null 2>&1
然后
    测试 "`tput 颜色`" -gt 2 && colour=1
菲

进一步阅读

  • 乔纳森·德·博因·波拉德 (2018)。TERM. 小吃指南。软件。

  • 此外,`tput Co` 在 Jessie 和 Xenial 中返回“未知的 terminfo 能力”。`tput colours` 和 `tput setaf 1` 似乎都有效,尽管我承认我不明白*为什么*。 (2认同)

egm*_*ont 5

请参阅https://askubuntu.com/a/614714/398785详细回答我为什么认为这TERM=xterm-color是错误的方法而 Ubuntu.bashrc已经过时。我建议您使用TERM=xterm-256color(这是自 gnome-terminal 3.16 以来的默认设置,但也可以安全地与较旧的 gnome-terminal 一起使用),并相应地调整您的.bashrc