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

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

我的电脑上有 Ubuntu,并且正在运行超棒的窗口管理器。如何检查我正在运行哪个终端?有命令吗?

答案1

总结

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

    您说的“哪个”是什么意思?单击“帮助 --> 关于”,是这个吗?–小丑

Shell 与终端

首先我们需要弄清楚的是到底在问什么——找出正在运行的 shell 或正在运行的终端。这两个术语通常可以互换使用,但它们完全是不同的东西。Shell 是命令行解释器,具体来说,交互式 shell 是提示符加上您输入命令的文本字段。Shell 也可以是非交互式的,例如,脚本启动非交互式 shell,或者bash -c 'echo hello world'也启动非交互式 shell。

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

获取 shell 信息

每个用户都有一个为其用户名分配的默认 shell /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% 的情况下都有效。当然,有些方法可以被破坏。例如,如果在 shell 启动后不久删除了可执行文件,则符号链接将不会指向任何地方(在这种情况下,您可能会遇到系统问题,因为不建议删除/bin/sh/bin/dash甚至/bin/bash- 毕竟很多脚本都依赖它们,尤其是系统级脚本)。shell 的命令名称通常设置为 syscall 中的第一个参数execve()。这在bash 如何知道它是如何被调用的?,因此如果您有一个通过 启动 shell 的应用程序execve(),则可以为其指定任何名称。但这些都是非标准和非典型的东西,为了一致性和安全性,应该避免。


获取终端信息

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

$ 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。当然,如果您使用的是交互式 shell,此方法将有效。例如,如果我们试图找出 的父级bash -c '...'或通过 启动的 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

答案2

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

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

打开终端(shell)后立即运行此命令无需分叉任何其他 shell 实例

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

这里我们通过 找到 shell 的父进程 ID (PPID)(bashps -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

答案3

简短版本(谢谢@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'.

答案4

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

相关内容