52

I have Ubuntu on my machine and I am running awesome window manager on top of it. How do I check which terminal I am running? Is there a command for it?

3
  • 7
    what do you mean by which? Click Help --> About is that it?
    – JoKeR
    Jun 23, 2015 at 19:34
  • 4
    Which terminal meaning the terminal program or the shell ?
    – heemayl
    Jun 23, 2015 at 19:37
  • 1
    you can see if you are using bash or zsh by doing ps usually it works and there are only a few processes. Mar 4, 2021 at 22:01

10 Answers 10

69

TL;DR

  • to find currently running shell use ls -l /proc/$$/exe
  • to find currently running terminal, use xprop _NET_WM_PID WM_CLASS. The value of pid later can be passed to ps -p <pid> -o args command.
  • Technically, for terminal emulator you don't even need a command, as stated in the comments:

    what do you mean by which? Click Help --> About is that it? – JoKeR

Shell vs Terminal

First thing we need to have clarified is what exactly is being asked - find out the running shell or running terminal. Often these two terms are used interchangeably, but they are different things altogether. Shell is the command-line interpreter, specifically interactive shell is the prompt plus text field where you enter commands. Shells can also be non-interactive, for example a script starts non-interactive shell, or bash -c 'echo hello world' also starts non-interactive shell.

By contrast, terminal is the interface to shell ( though it could be another application as well). Originally terminal referred to actual hardware, but nowadays they're mostly software. What you see when you press Ctrl+Alt+t or click on the terminal icon in GUI, that starts a terminal emulator, a window which mimics behavior of hardware, and within that window you can see the shell running. Ctrl+Alt+F2 (or any of the 6 function keys) will open virtual console, aka tty. I recommend reading Why is a virtual terminal “virtual”, and what/why/where is the “real” terminal? for more info on the specifics.

Getting the shell information

Each user has a default shell assigned to them in /etc/passwd for their username. Assuming you are using default configuration and haven't called another shell explicitly as a command, it is sufficient to do:

echo $SHELL

But of course this only shows default value. Suppose we do the following:

user@ubuntu:~$ dash
$

We were originally in bash, but started interactive session of /bin/dash, Ubuntu's POSIX or system shell. The variable $SHELL won't change, because that's not its purpose - it shows default not current value. We will need to approach this from another perspective - the perspective of a process, which is something I've covered in Am I using bash or sh?

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

Here we take advantage of /proc/ filesystem. The name of the process and command-line parameters are displayed in /proc/<pid>/comm. All we need is to provide shell's PID, which is what $$ does. In the example above I am adding that separately, but there is nothing stopping us from doing just

cat /proc/$$/comm

Variation on the theme could also be

ps -p $$ -o args

Another way we could approach this is via checking where /proc/<pid>/exe. This file is a symlink that points to the executable file. Thus we can do

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

Either of the two approaches works in 99% of the cases. Of course, there are ways in which they can be subverted. For instance, symlink won't point anywhere if the executable was deleted shortly after the shell started ( and in that case you probably will encounter system issues, since removing /bin/sh, /bin/dash, or even /bin/bash is not recommended - after all a lot of scripts rely on them, especially system-level ones). Command name for shell is usually set as the very first argument in execve() syscall. This is covered in How does bash know how it is being invoked? , so if you have an application that launches a shell via execve(), it could give it any name. But these are non-standard and non-typical things, that should be avoided for the sake of consistency and security.


Getting Terminal Information

We can start with the environment variables. Many terminals seem to mask themselves as xterm-compatible, which is reported by echo $TERM or echo $COLORTERM. But then environment variables are not very reliable tool. They can be set and unset. We can do the same thing with PIDs again, except this time we will look at parent PID. As you may remember, terminal is the interface to the shell and often starts the shell itself. Therefore we can find out what process is the parent process of our shell:

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

Let's try with another terminal app, sakura:

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

From there we can already see that what started this shell is gnome-terminal. This method of course works assuming you're working with interactive shell. If we're trying to find out the parent of bash -c '...' or the shell started via ssh, for example, PID may very well be from non-terminal application and maybe non-GUI at all.

So if we want to specifically deal with GUI terminal, what we can do is run xprop, click on the desired window, grep its pid, and find out what's the name of that process matching pid. Or in other words:

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

Additionally, as per specifications , window managers should set WM_CLASS property. Thus, we can get that from xprop as well:

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

Of course, this also has its 1% of disadvantages: setting WM_CLASS properties relies on window manager doing that, and PID is not guaranteed for a window to be accurate ( see What process created this X11 window? ), which may involve complex debugging. And these aren't shortcomings of the methods themselves but of X11 server. However, most stable and well known window managers ( like openbox, Metacity, blackbox ) and most applications are well behaved so we shouldn't expect problems with something like Gnome Terminal or Terminator.

But when it comes to GUI terminal emulators, we don't even need to find a command. We can just use the About dialog of the window itself. Exception to that rule is xterm.

5
  • 1
    O_o $SHELL, sure
    – A.B.
    Jun 23, 2015 at 19:59
  • 1
    Eek. Why do you people use ps | grep? ps -p $$! Or, just for the command, ps -p $$ -o cmd=.
    – muru
    Jun 23, 2015 at 20:36
  • 1
    NOTE: I've updated my answer, since this question overall was originally unclear, and parts of it require some background; over time I also figured out there's better ways to invoke commands. Apr 5, 2019 at 1:21
  • 1
    WARNING: do not use xprop _NET_WM_PID WM_CLASS as your system will lock up and freeze!
    – user587469
    Oct 23, 2021 at 7:03
  • 1
    When I try ps -p $$ -o args,ppid in Git Bash, I get ps: unknown option -- o Jul 22, 2022 at 16:43
22

If you want to know the terminal program you are using, use this:

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

Run this just after opening the terminal (shell) without forking any further shell instance.

When you open up the terminal program, it basically spawns a child program, a shell. So the parent of the spawned shell is the terminal itself. In other words, the PPID of the shell is the PID of terminal program.

Here we are finding the parent process ID (PPID) of the shell (bash) by ps -o 'ppid=' -p $$ , which will be the process ID of terminal program.

Then we are finding the process name from the PID:

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

It is basically a one liner of:

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

$ ps -o 'cmd=' -p 2268
gnome-terminal
2
  • 3
    When I run this command I get sshd: username@pts/4. Note I'm using PuTTY to connect to the machine. Is sshd actually the terminal emulator? Mar 21, 2018 at 17:21
  • 1
    @user3731622, did you find an answer to this question? Did you ask it elsewhere? Jan 24, 2022 at 19:17
17

The short version (thx @Serg)

cat /etc/alternatives/x-terminal-emulator

The long version

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

and look for the * in the output

;)


Example output

There are 7 alternatives which provide `x-terminal-emulator’.
Selection Alternative
———————————————–
    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:

Or, thanks to @muru, here is more detailed output

$ 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'.
6
  • 3
    cat /etc/alternatives/x-terminal-emulator | grep exec Jun 23, 2015 at 19:59
  • 1
    Is there a utility I need installed? I get either Binary file (standard input) matches or update-alternatives: error: unknown argument –config'`
    – Terrance
    Jun 23, 2015 at 20:06
  • 1
    Nevermind, it is --config
    – Terrance
    Jun 23, 2015 at 20:06
  • 2
    You don't need sudo. Use update-alternatives --display x-terminal-emulator
    – muru
    Jun 23, 2015 at 20:34
  • 1
    For the short version you might consider using file /etc/alternatives/x-terminal-emulator to get the target of this symbolic link instead using cat on it. The file utility should be installed on most systems and can be used to find the target executable. cat on symbolic link could print any shell script or even binary file depending on the target of this link (shell script for gnome-terminal, binary file urxvt, etc.).
    – chris544
    Jul 18, 2017 at 3:40
5

Use tty - prints the file name of the terminal connected to standard input.

In gnome-terminal:

 $ tty
 /dev/pts/2

In a virtual terminal (ALT+F4):

 $ tty
 /dev/tty4
4

If you just want the name of the terminal program, you'll most probably find it under Help > About.

2

The best way is to install neofectch

sudo apt install neofetch

Just type the below given command and checkout the terminal

neofetch
1
cat /etc/alternatives/x-terminal-emulator | grep exec

Sample output:

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

There's the answer for my system: gnome-terminal.

So, typing gnome-terminal into my terminal will now open up another identical terminal window.

Sources:

0

Run neofetch and it will tell you.

1
0

When it is run in an interactive shell, the solution proposed by heemayl ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$) accurately retrieves the terminal program, which is the parent of the shell. Within a script, however, the immediate parent is the invoking shell, not the terminal. Consequently, this command yields the shell name — Bash, in my case — when executed within a script. To address this, one could traverse up the process tree from the script, examining the parent of each shell process until encountering a non-shell process. This non-shell process is then presumed to be the terminal program.

Bash:

pid=$$
while true; do
    cmd=$(ps -o 'cmd=' -p $pid | cut -d ' ' -f 1)
    if [[ "$cmd" != "bash" ]]; then
        terminal=$cmd
        break
    fi
    pid=$(ps -o 'ppid=' -p $pid)
done
echo $terminal

Other shells:

pid=$$
while true; do
    cmd=$(ps -o 'cmd=' -p $pid | cut -d ' ' -f 1)
    case "$cmd" in
        bash|sh|csh|ksh|zsh|fish) ;;
        *) terminal=$cmd; break ;;
    esac
    pid=$(ps -o 'ppid=' -p $pid)
done
echo $terminal
-1

Simple answer. Works for both console or ssh.

Example for simple character terminal:

ssh username@systemname
echo $TERM
dumb

tells you that you can't open GUI apps on that connection

Example for xterm (also works with PuTTY/Xming on Windows)

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

means that you can use GUI commands like opening the leafpad editor or nautilus file manager.

On the console it is the same:

Open terminal window
echo $TERM
xterm
1
  • TERM is not a variable that defines the default terminal emulator, but rather one that defines the capabilities of the current one. For example, setting the variable to "xterm-color" lets any program running in the terminal know that the current terminal is supposed to understand colours; setting it to "linux" tells programs that this is supposed to be a VT; etc.
    – Cybolic
    Dec 7, 2017 at 0:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .