很多地方,视情况而定

很多地方,视情况而定

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

如果我使用++CTL切换到控制台TTY窗口并且该值设置为.ALTF1echo $TERMlinux

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

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

如果我输入,在控制台 shell 和 Gnome 终端模拟器 shell 中

export TERM=xterm-color
source /.bashrc

两个外壳都更改为颜色模式(我希望这两个外壳都始终发生这种情况)。

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

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

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

答案1

很多地方,视情况而定

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

真实终端

真实的串行终端的类型可能有所不同,具体取决于电线另一端的情况。因此,按照惯例,getty程序是用指定终端类型的参数来调用的,或者TERM从服务管理器的服务配置数据传递给程序。

  • 在 van Smoorenburginit系统上,人们可以在/etc/inittab条目中看到这一点,该条目将读取类似于以下内容的内容:

    S0:3:重生:/sbin/agetty ttyS0 9600 vt100-nav
    agetty该行中的最后一个参数vt100-nav是为 设定的终端类型/dev/ttyS0。因此,/etc/inittab在此类系统上更改真实终端的终端类型也是如此。
  • 在 systemd 系统上,人们过去能够在单元文件(在未合并的系统上)中看到这一点,该文件用于读取/usr/lib/systemd/system/[email protected]/lib/systemd/system/[email protected]

    环境=术语=vt100
    TERM在传递给的环境中设置变量agetty
  • 在 BSD 上,init从数据库中每个终端条目的第三个字段获取终端类型/etc/ttys,并根据TERM它执行的环境中的类型进行设置getty/etc/ttys更改 BSD 上真实终端的终端类型也是如此。

systemd 的可变性

服务[email protected]单元文件或适用于此的插入文件是在 systemd 系统上更改真实终端的终端类型的地方。请注意,此类更改适用于全部使用此服务单元模板的终端登录服务。 (要仅针对单个终端更改它,必须手动实例化模板,或添加仅适用于实例化的插件。)

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

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

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

内核虚拟终端

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

  • mingetty在使用或(来自 nosh 包)的系统上,vc-get-tty程序“知道”它只能与虚拟终端通信,并且它们硬连线适合该程序编译的操作系统的“已知”虚拟终端类型。
  • 在 systemd 系统上,人们过去能够在单元文件(在未合并的系统上)中看到这一点,该文件读取/usr/lib/systemd/system/[email protected]/lib/systemd/system/[email protected]

    环境=术语=linux
    TERM在传递给的环境中设置变量agetty

对于内核虚拟终端,一才不是更改终端类型。毕竟,内核中的终端仿真器程序没有改变。这是不正确更改类型。特别是,这会搞砸光标/编辑键 CSI 序列识别。 Linux 内核终端仿真器发送的 CSI序列与 DEC VT 模式下 GUI 终端仿真器程序发送的 CSI 序列不同linux。(事实上​​,它们非常特殊且非标准,并且与我所知道的所有真实终端以及除了 Linux 内置的终端仿真器之外的几乎所有其他软件终端仿真器都不同。)xtermvt100

GUI 终端模拟器

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

紧握的手

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

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

颜色=0
if tput Co > /dev/null 2>&1
然后
测试“`tput Co`”-gt 2 && color=1
elif tput 颜色 > /dev/null 2>&1
然后
测试“`tput color`”-gt 2 && color=1

进一步阅读

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

答案2

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

答案3

对于 Linux,在初始化/main.c该环境定义为:

static const char *argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
const char *envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };

然后打电话给do-execve():

static int run_init_process(const char *init_filename)
{
    argv_init[0] = init_filename;
    pr_info("Run %s as init process\n", init_filename);
    return do_execve(getname_kernel(init_filename),
        (const char __user *const __user *)argv_init,
        (const char __user *const __user *)envp_init);
}

pr_info()显示为:

]# dmesg |grep 'Run'
[    1.291323] Run /init as init process

所以从一开始默认就是“TERM=linux”。

相关内容