Lorsque j'ouvre une fenêtre de terminal avec l'émulateur de terminal GNOME dans l'interface graphique du bureau, la variable d'environnement Shell TERM prend par défaut la valeur xterm
.
Si j'utilise CTL+ALT+F1 pour passer à une fenêtre TTY de la console et echo $TERM
la valeur est définie sur linux
.
Ma motivation pour demander est qu'à l'intérieur de mon ~/.bashrc
fichier une variable est utilisée pour déterminer si un Shell couleur est fourni ou juste un bon vieux monochrome.
# set a fancy Prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color) color_Prompt=yes;;
esac
Dans le shell de la console et le shell de l'émulateur de terminal Gnome si je tape
export TERM=xterm-color
source /.bashrc
les deux coques passent en mode couleur (quelque chose que j'aimerais qu'il se passe toujours dans les deux).
Où les valeurs par défaut TERM
sont-elles définies, et où est le meilleur endroit pour modifier leurs valeurs par défaut, si possible? Il ne semble y avoir rien dans l'interface graphique de l'émulateur de terminal pour sélectionner ou définir la valeur TERM par défaut.
J'ai envisagé d'ajouter simplement la ligne export TERM=xterm-color
en haut de mon ~/.bashrc
file mais mon instinct me dit que ce n'est pas la meilleure solution et mes recherches sur Google ne m'ont pas encore conduit à une bonne réponse.
J'utilise Ubuntu 15.04 Desktop Edition (basé sur Debian).
Sur les terminaux virtuels et les terminaux réels, la variable d'environnement TERM
est définie par le programme qui s'enchaîne sur login
, et est héritée tout au long du shell interactif qui s'exécute une fois connecté . Lorsque cela se produit précisément, cela varie d'un système à l'autre et selon le type de terminal.
Les terminaux réels et série peuvent varier en type, selon ce qui se trouve à l'autre extrémité du fil. Ainsi, par convention, le programme getty
est appelé avec un argument qui spécifie le type de terminal, ou le programme TERM
est transmis à partir des données de configuration de service d'un gestionnaire de services.
init
, on peut le voir dans les entrées /etc/inittab
, Qui liront quelque chose comme S0: 3: réapparition:/sbin/agetty ttyS0 9600 vt100-navLe dernier argument de
agetty
dans cette ligne, vt100-nav
, Est le type de terminal défini pour /dev/ttyS0
. /etc/inittab
Est donc l'endroit où changer le type de terminal pour les terminaux réels sur de tels systèmes./usr/lib/systemd/system/[email protected]
(/lib/systemd/system/[email protected]
Sur les systèmes non fusionnés), qui lisait Environnement = TERM = vt100définissant la variable
TERM
dans l'environnement passé à agetty
.init
prend le type de terminal dans le troisième champ de l'entrée de chaque terminal dans la base de données /etc/ttys
, Et définit TERM
à partir de celui de l'environnement qu'il exécute getty
avec. Donc /etc/ttys
Est l'endroit où l'on change le type de terminal pour les terminaux réels sur les BSD.Le fichier d'unité de service [email protected]
, Ou les fichiers de dépôt qui s'y appliquent, permet de modifier le type de terminal pour les terminaux réels sur les systèmes systemd. Notez qu'une telle modification s'applique à tous les services de connexion au terminal qui utilisent ce modèle d'unité de service. (Pour le modifier uniquement pour les terminaux individuels, il faut instancier manuellement le modèle ou ajouter des drop-ins qui ne s'appliquent qu'aux instanciations.)
systemd a eu au moins quatre mécanismes au cours de sa vie pour récupérer la valeur de la variable d'environnement TERM
. Au moment de la première rédaction de cette réponse, comme on peut le voir, il y avait une ligne Environment=TERM=something
Dans les fichiers d'unité de service modèle. À d'autres moments, les types linux
et vt102
Étaient câblés dans les fichiers d'unité de service getty
et serial-getty
Respectivement. Plus récemment, la variable d'environnement a été héritée du processus n ° 1, qui l'a définie de différentes manières.
À partir de 2020, la façon dont systemd décide du type de terminal à spécifier dans la variable d'environnement TERM
d'un service est assez complexe et n'est pas du tout documentée. Le moyen de le changer reste un fichier de configuration de dépôt avec Environment=TERM=something
. Mais d'où provient la valeur par défaut est assez variable. Sous réserve de règles assez complexes pour expliquer les règles qui impliquent les paramètres TTYPath=
Des unités de service individuelles, il peut s'agir de l'une des trois valeurs : un câblé linux
, un câblé vt220
(Plus vt102
), Ou la valeur de la variable d'environnement TERM
qui traite le # 1 hérité, généralement du chargeur noyau/bootstrap.
(Ironiquement, le mécanisme getttyent()
existe toujours dans la bibliothèque GNU C, et systemd aurait pu réutiliser le mécanisme /etc/ttys
.)
Les terminaux virtuels du noyau, comme vous l'avez noté, ont un type fixe. Contrairement à NetBSD, qui peut varier à la volée le type de terminal virtuel du noyau, Linux et les autres BSD ont un seul type de terminal fixe implémenté dans le programme d'émulation de terminal intégré du noyau. Sous Linux, ce type correspond à linux
de la base de données terminfo. (L'émulation du terminal noyau de FreeBSD depuis la version 9 a été teken
. Avant la version 9, c'était cons25
OpenBSD est pccon
.)
mingetty
ou vc-get-tty
(Du paquet nosh) le programme "sait" qu'il ne peut parler qu'à un terminal virtuel, et ils câblent les types de terminaux virtuels "connus" appropriés pour le système d'exploitation pour lequel le programme a été compilé./usr/lib/systemd/system/[email protected]
(/lib/systemd/system/[email protected]
Sur les systèmes non fusionnés), qui indiquait Environnement = TERM = linuxdéfinissant la variable
TERM
dans l'environnement passé à agetty
.Pour les terminaux virtuels du noyau, un ne change pas le type de terminal. Le programme d'émulation de terminal dans le noyau ne change pas, après tout. Il est incorrect de changer le type. En particulier, cela vissera la reconnaissance de séquence CSI du curseur/touche d'édition. Les séquences CSI linux
envoyées par l'émulateur de terminal du noyau Linux sont différentes des séquences CSI xterm
ou vt100
Envoyées par les programmes d'émulation de terminal GUI en mode DEC VT. (En fait, ils sont très idiosyncratiques et non standard, et différents à la fois de tous les terminaux réels que je connais et de pratiquement tous les autres émulateurs de terminaux logiciels, à l'exception de celui intégré à Linux.)
Votre émulateur de terminal GUI est l'un des nombreux programmes, du démon SSH à screen
, qui utilise des pseudo-terminaux. Le type de terminal dépend du programme d'émulation de terminal qui s'exécute du côté maître du pseudo-terminal et de sa configuration. La plupart des émulateurs de terminaux GUI démarrent le programme côté esclave avec une variable TERM
dont la valeur correspond à leur émulation de terminal côté maître. Des programmes tels que le serveur SSH tenteront de "passer" le type de terminal qui se trouve à l'extrémité client de la connexion. Habituellement, il existe un menu ou une option de configuration à choisir parmi les émulations de terminal.
La bonne façon de détecter la capacité de couleur est et non de câbler une liste de types de terminaux dans votre script. Il existe énormément de types de terminaux qui prennent en charge la couleur.
La bonne façon est de regarder ce que termcap/terminfo dit sur votre type de terminal.
color = 0 si tput Co>/dev/null 2> & 1 puis test "` tput Co` "-gt 2 && color = 1 Elif tput colors>/dev/null 2> & 1 puis test "` tput colors` "-gt 2 && color = 1 fi
TERM
. Guide de nosh . Logiciels.Veuillez voir https://askubuntu.com/a/614714/398785 pour ma réponse détaillée sur les raisons pour lesquelles je pense TERM=xterm-color
n'est pas la bonne approche et le Ubuntu .bashrc
est obsolète. Je vous recommande d'aller avec TERM=xterm-256color
(qui est la valeur par défaut depuis gnome-terminal 3.16, mais également sûr à utiliser avec les anciens gnome-terminaux), et ajustez votre .bashrc
en conséquence.
Pour Linux, dans init/main.c cet environnement est défini:
static const char *argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
const char *envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
puis appelé avec 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);
}
Cette pr_info () apparaît comme:
]# dmesg |grep 'Run'
[ 1.291323] Run /init as init process
La valeur par défaut est donc "TERM = linux", dès le début.