如何检查我正在使用哪个终端?


Answers:


24

TL; DR

  • 查找当前正在运行的shell使用 ls -l /proc/$$/exe
  • 要查找当前正在运行的终端,请使用xprop _NET_WM_PID WM_CLASS。以后的值pid可以传递给ps -p <pid> -o args命令。
  • 从技术上讲,对于终端仿真器,您甚至不需要命令,如注释中所述:

    你是什​​么意思?单击帮助->关于吗?– 约克

外壳与终端

我们需要弄清的第一件事是确切的要求-查找正在运行的shell或正在运行的终端。通常这两个术语可以互换使用,但是它们是完全不同的东西。Shell是命令行解释器,特别是交互式Shell是您在其中输入命令的提示加文本字段。Shell也可以是非交互式的,例如脚本启动非交互式Shell,或者bash -c 'echo hello world'也可以启动非交互式Shell。

相比之下,终端是Shell的接口(尽管它也可以是另一个应用程序)。最初,终端是指实际的硬件,但如今,它们主要是软件。当您按Ctrl+ Alt+ t或单击GUI中的终端图标时,您会看到的内容将启动终端仿真器,这是一个模拟硬件行为的窗口,在该窗口中您可以看到外壳正在运行。Ctrl+ Alt+ F2(或任何的6个功能键的)将打开虚拟控制台,又名tty。我建议阅读为什么虚拟终端是“虚拟的”,“真实”终端是什么/为什么/在哪里?有关详细信息的更多信息。

获取外壳信息

每个用户都有一个默认的外壳程序分配给他们/etc/passwd作为用户名。假设您使用的是默认配置,并且没有显式调用另一个shell作为命令,那么只需执行以下操作:

echo $SHELL

但是当然,这仅显示默认值。假设我们执行以下操作:

user@ubuntu:~$ dash
$

我们最初在bash,但开始的互动环节/bin/dashUbuntu的POSIX或系统shell。该变量$SHELL不会更改,因为这不是其目的-它显示默认值而不是当前值。我们将需要从另一个角度来解决这个问题-过程的角度,这是我在使用bash或sh进行介绍的内容吗?

$ echo $$
4824
$ cat /proc/4824/comm                                                          
mksh
$ bash
xieerqi@eagle:~$ echo $$
6197
xieerqi@eagle:~$ cat /proc/6197/comm
bash

在这里,我们利用/proc/文件系统。进程的名称和命令行参数显示在中/proc/<pid>/comm。我们所需要做的就是提供shell的PID,它可以做什么$$。在上面的示例中,我将其单独添加,但是没有什么可以阻止我们仅仅做

cat /proc/$$/comm

主题的变化也可能是

ps -p $$ -o args

我们可以采用的另一种方法是通过检查where /proc/<pid>/exe。该文件是指向可执行文件的符号链接。这样我们可以做

user@ubuntu:~$ ls -l /proc/$$/exe
lrwxrwxrwx 1 adminx adminx 0 Apr  4 18:20 /proc/1241/exe -> /bin/bash
user@ubuntu:~$ sh
$ ls -l /proc/$$/exe
lrwxrwxrwx 1 adminx adminx 0 Apr  4 18:20 /proc/1255/exe -> /bin/dash

两种方法都可以在99%的情况下使用。当然,有一些可以颠覆它们的方法。例如,如果在外壳启动后不久就删除了可执行文件,则symlink不会指向任何位置(在这种情况下,您可能会遇到系统问题,因为建议不要删除/bin/sh,,/bin/dash甚至/bin/bash不建议这样做-毕竟很多脚本都依赖它们,尤其是系统级的)。Shell的命令名称通常设置为execve()syscall中的第一个参数。bash如何知道如何调用它涵盖了这一点?,因此,如果您有一个通过来启动Shell的应用程序execve(),则可以为其指定任何名称。但是,这些都是非标准和非典型的事情,出于一致性和安全性的考虑,应避免使用。


获取终端信息

我们可以从环境变量开始。许多终端似乎将自己掩盖为xterm-compatible,这是由echo $TERM或报告的echo $COLORTERM。但是,环境变量并不是一个非常可靠的工具。可以设置和取消设置。我们可以再次对PID执行相同的操作,除了这次我们将查看父PID。您可能还记得,终端是Shell的接口,通常会启动Shell本身。因此,我们可以找出壳的父进程是什么进程:

$ ps -p $$ -o args,ppid
COMMAND                      PPID
bash                         1234
$ ps -p 1234 -o args
COMMAND
/usr/lib/gnome-terminal/gnome-terminal-server

让我们尝试另一个终端应用程序sakura

$ ps -p $$ -o args,ppid
COMMAND                      PPID
/bin/bash                   16950
$ ps -p 16950 -o args
COMMAND
sakura

从那里我们已经可以看到开始这个shell的是gnome-terminal。假设您使用的是交互式外壳,那么这种方法当然可以工作。例如,如果我们试图找出bash -c '...'通过或Windows启动的shell 的父ssh对象,则PID很可能来自非终端应用程序,也可能完全来自非GUI。

因此,如果我们要专门处理GUI终端,我们可以做的是运行xprop,单击所需的窗口,grep它的pid,然后找出与pid匹配的进程的名称。换句话说:

$ ps aux | grep $(xprop | awk -F'='  '/PID/ {print $2}')                       
xieerqi   2124  0.6  1.7 208068 34604 ?        Sl   18:47   1:49 gnome-terminal

另外,根据规范,窗口管理器应设置WM_CLASS属性。因此,我们也可以从中得到xprop

$ xprop WM_CLASS 
WM_CLASS(STRING) = "sakura", "Sakura"

当然,这也有1%的缺点:设置WM_CLASS属性依赖于窗口管理器来做到这一点,并且不能保证PID保证窗口的准确性(请参阅创建此X11窗口的进程是什么?),这可能涉及复杂的调试。这些不是方法本身的缺点,而是X11服务器的缺点。但是,大多数稳定且广为人知的窗口管理器(例如openbox,Metacity,blackbox)和大多数应用程序的行为都很好,因此我们不应该期望Gnome Terminal或Terminator之类的问题。

但是,对于GUI终端仿真器,我们甚至不需要查找命令。我们可以只使用About窗口本身的对话框。该规则的例外是xterm


O_o $SHELL,确定
AB

真是的 你们为什么使用ps | grepps -p $$!或者,仅对于命令而言ps -p $$ -o cmd=
muru

@muru,因为我比您经验不足,而且我没有记住所有的ps标志> _ <直言不讳
Sergiy Kolodyazhnyy 2015年

2
我也不ps | grep是,只是形式不好。您可以grep进行的大部分操作实际上都可以通过ps自身或其他工具获得。
muru

注意:我已经更新了答案,因为这个问题本来就不清楚,而且部分内容需要一些背景知识;随着时间的流逝,我还发现有更好的方法来调用命令。
Sergiy Kolodyazhnyy

12

简短版本(thx @Serg

cat /etc/alternatives/x-terminal-emulator

长版

sudo update-alternatives --config x-terminal-emulator

*在输出中寻找

;)


输出示例

There are 7 alternatives which provide `x-terminal-emulator’.
选择替代
———————————————
    1 / usr / bin / xterm
    2 / usr / bin / uxterm
    3 / usr / bin / koi8rxterm
    4 / usr / bin / lxterm
 * + 5 /usr/bin/gnome-terminal.wrapper
    6 / usr / bin / konsole
    7 /usr/bin/xfce4-terminal.wrapper
Press enter to keep the default[*], or type selection number:

或者,由于@muru,这里是更详细的输出

$ update-alternatives --display x-terminal-emulator
x-terminal-emulator - auto mode
  link currently points to /usr/bin/gnome-terminal.wrapper
/usr/bin/gnome-terminal.wrapper - priority 40
  slave x-terminal-emulator.1.gz: /usr/share/man/man1/gnome-terminal.1.gz
/usr/bin/koi8rxterm - priority 20
  slave x-terminal-emulator.1.gz: /usr/share/man/man1/koi8rxterm.1.gz
/usr/bin/lxterm - priority 30
  slave x-terminal-emulator.1.gz: /usr/share/man/man1/lxterm.1.gz
/usr/bin/mate-terminal.wrapper - priority 30
  slave x-terminal-emulator.1.gz: /usr/share/man/man1/mate-terminal.1.gz
/usr/bin/uxterm - priority 20
  slave x-terminal-emulator.1.gz: /usr/share/man/man1/uxterm.1.gz
/usr/bin/xterm - priority 20
  slave x-terminal-emulator.1.gz: /usr/share/man/man1/xterm.1.gz
Current 'best' version is '/usr/bin/gnome-terminal.wrapper'.

2
cat /etc/alternatives/x-terminal-emulator | grep exec
Sergiy Kolodyazhnyy 2015年

我需要安装实用程序吗?我得到任何Binary file (standard input) matchesupdate-alternatives: error: unknown argument -config'`
特伦斯

没关系,这是--config
Terrance

1
您不需要sudo。使用update-alternatives --display x-terminal-emulator
大师

对于简短版本,您可以考虑使用 file /etc/alternatives/x-terminal-emulator获取此符号链接的目标,而不是cat在其上使用。该file实用程序应该安装在大多数系统上,并且可以用于查找目标可执行文件。cat在符号链接上,可以打印任何shell脚本,甚至可以打印二进制文件,具体取决于此链接的目标(gnome-terminal,二进制文件urxvt等的shell脚本)。
chris544

9

如果您想知道正在使用的终端程序,请使用以下命令:

ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)

仅在打开终端(外壳)之后运行此程序,而不派生任何其他外壳实例

当您打开终端程序时,它基本上会生成一个子程序,即shell。因此,生成的外壳的父级是终端本身。换句话说,外壳的PPID是终端程序的PID。

在这里,我们通过找到shell(bash)的父进程ID(PPID)ps -o 'ppid=' -p $$,它将是终端程序的进程ID。

然后我们从PID中找到进程名称:

$ ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
gnome-terminal

它基本上是以下内容的一个衬里:

$ ps -o 'ppid=' -p $$
 2268

$ ps -o 'cmd=' -p 2268
gnome-terminal

1
当我运行此命令时,我得到了sshd: username@pts/4。注意我正在使用PuTTY连接到计算机。是sshd真正的终端仿真器?
user3731622 '18

3

printenv从终端窗口中键入以查看打开的会话的所有变量。

输入echo $COLORTERM从终端窗口。 注意:这不适用于所有终端,例如sakura不会报告此情况。

root@terrance-Linux:~# echo $COLORTERM
gnome-terminal

下面的一个来自aterm终端。

root@terrance-Linux:~$ echo $COLORTERM
rxvt-xpm

在樱花中回显$ COLORTERM报告空白
Sergiy Kolodyazhnyy 2015年

@Serg谢谢。看来这是xterm的变体。
Terrance 2015年

@Serg想知道您是否喜欢樱花?什么吸引您呢?
Terrance 2015年

没关系,没有什么特别的,很简单的。我尝试了各种终端仿真器:终结器,roxterm,代字号,下拉菜单(忘记了它的名称,以R开头的东西)。我想这是xterm和GNOME终端之间的妥协
谢尔盖Kolodyazhnyy

@Serg Ah,很高兴知道。我要检查一下。:-)我一直在寻找一个可以与我的keepalive脚本配合使用的好终端,该脚本向它们发送xdotool密钥。
Terrance 2015年

3

如果只需要终端程序的名称,则很有可能在“帮助”>“关于”下找到它。


0
cat /etc/alternatives/x-terminal-emulator | grep exec

样本输出:

exec('gnome-terminal',@ args);

我的系统有答案:gnome-terminal

因此,gnome-terminal现在输入我的终端将打开另一个相同的终端窗口。

资料来源:


-1

简单的答案。适用于控制台或ssh。

简单字符终端的示例:

ssh username@systemname
echo $TERM
dumb

告诉您无法在该连接上打开GUI应用程序

xterm的示例(在Windows上也适用于PuTTY / Xming)

ssh -Y username@systemname      -- omit this if using PuTTY --
echo $TERM
xterm

表示您可以使用GUI命令,例如打开Leafpad编辑器或Nautilus文件管理器。

在控制台上是相同的:

Open terminal window
echo $TERM
xterm

TERM不是定义默认终端仿真器的变量,而是定义当前终端仿真器功能的变量。例如,将变量设置为“ xterm-color”可使终端中运行的任何程序都知道当前终端应理解颜色;将其设置为“ linux”会告诉程序这应该是VT。等
Cybolic
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.