如何检查我使用的是哪个终端?

use*_*481 32 command-line gnome-terminal

我的机器上有 Ubuntu,我在它上面运行了很棒的窗口管理器。如何检查我正在运行哪个终端?有命令吗?

Ser*_*nyy 41

TL; 博士

  • 查找当前正在运行的 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 中的终端图标时,您会看到什么,这将启动一个终端模拟器,一个模拟硬件行为的窗口,在该窗口中您可以看到 shell 正在运行。Ctrl+ Alt+ F2(或任何的6个功能键的)将打开虚拟控制台,又名tty。我建议阅读为什么虚拟终端是“虚拟的”,“真实”终端是什么/为什么/在哪里?有关详细信息的更多信息。

获取外壳信息

每个用户都有一个/etc/passwd为其用户名分配的默认 shell 。假设您使用的是默认配置并且没有显式调用另一个 shell 作为命令,那么执行以下操作就足够了:

echo $SHELL
Run Code Online (Sandbox Code Playgroud)

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

user@ubuntu:~$ dash
$
Run Code Online (Sandbox Code Playgroud)

我们最初在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
Run Code Online (Sandbox Code Playgroud)

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

cat /proc/$$/comm
Run Code Online (Sandbox Code Playgroud)

主题的变化也可以

ps -p $$ -o args
Run Code Online (Sandbox Code Playgroud)

我们可以解决这个问题的另一种方法是通过检查 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
Run Code Online (Sandbox Code Playgroud)

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


获取终端信息

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

$ ps -p $$ -o args,ppid
COMMAND                      PPID
bash                         1234
$ ps -p 1234 -o args
COMMAND
/usr/lib/gnome-terminal/gnome-terminal-server
Run Code Online (Sandbox Code Playgroud)

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

$ ps -p $$ -o args,ppid
COMMAND                      PPID
/bin/bash                   16950
$ ps -p 16950 -o args
COMMAND
sakura
Run Code Online (Sandbox Code Playgroud)

从那里我们已经可以看到启动这个 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
Run Code Online (Sandbox Code Playgroud)

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

$ xprop WM_CLASS 
WM_CLASS(STRING) = "sakura", "Sakura"
Run Code Online (Sandbox Code Playgroud)

当然,这也有它的 1% 的缺点:设置WM_CLASS属性依赖于窗口管理器这样做,并且不能保证窗口的 PID 准确(请参阅什么进程创建了这个 X11 窗口?),这可能涉及复杂的调试。这些不是方法本身的缺点,而是 X11 服务器的缺点。但是,大多数稳定且众所周知的窗口管理器(如 openbox、Metacity、blackbox)和大多数应用程序都表现良好,因此我们不应期望 Gnome Terminal 或 Terminator 之类的东西会出现问题。

但是当涉及到 GUI 终端模拟器时,我们甚至不需要找到命令。我们可以只使用About窗口本身的对话框。该规则的例外是xterm

  • 我也没有,但是`ps | grep` 只是不好的形式。您可以 grep 的大部分内容实际上都可以通过 `ps` 本身或其他工具获得。 (2认同)

A.B*_*.B. 13

简短版本(感谢@Serg

cat /etc/alternatives/x-terminal-emulator
Run Code Online (Sandbox Code Playgroud)

长版

sudo update-alternatives --config x-terminal-emulator
Run Code Online (Sandbox Code Playgroud)

*在输出中查找

;)


示例输出

There are 7 alternatives which provide `x-terminal-emulator’.
Run Code Online (Sandbox Code Playgroud)
备选方案
——————————————————
    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:
Run Code Online (Sandbox Code Playgroud)

或者,感谢@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'.
Run Code Online (Sandbox Code Playgroud)

  • `cat /etc/alternatives/x-terminal-emulator | grep exec` (2认同)
  • 你不需要`sudo`。使用“update-alternatives --display x-terminal-emulator” (2认同)

hee*_*ayl 13

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

ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
Run Code Online (Sandbox Code Playgroud)

在打开终端(shell)后立即运行它,而无需分叉任何进一步的 shell 实例

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

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

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

$ ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
gnome-terminal
Run Code Online (Sandbox Code Playgroud)

它基本上是一个班轮:

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

$ ps -o 'cmd=' -p 2268
gnome-terminal
Run Code Online (Sandbox Code Playgroud)

  • 当我运行此命令时,我得到 `sshd: username@pts/4`。注意我使用 PuTTY 连接到机器。“sshd”实际上是终端模拟器吗? (3认同)

Ter*_*nce 5

键入printenv从终端窗口查看公开会议的所有变量。

输入echo $COLORTERM从终端窗口。 注意:这不适用于所有终端,一个喜欢sakura不报告这个。

root@terrance-Linux:~# echo $COLORTERM
gnome-terminal
Run Code Online (Sandbox Code Playgroud)

下面的一个来自一个aterm终端。

root@terrance-Linux:~$ echo $COLORTERM
rxvt-xpm
Run Code Online (Sandbox Code Playgroud)


小智 5

使用tty- 打印连接到标准输入的终端的文件名。

gnome-terminal

 $ tty
 /dev/pts/2
Run Code Online (Sandbox Code Playgroud)

在虚拟终端 ( ALT+ F4) 中:

 $ tty
 /dev/tty4
Run Code Online (Sandbox Code Playgroud)