3

I have used pstree to find the name of the parent emulator of running shell script using something similar to the following:

pstree -s $PPID | awk -F '---' '{print $6}'

This works in my current system. I tested in mate-terminal and xterm but not sure if this will work on other Linux systems/platforms and other terminals. Is there a better/tidier (more portable way) way of achieving this?

6
ps -o comm= -p "$(($(ps -o ppid= -p "$(($(ps -o sid= -p "$$")))")))"

May give you good results. It gives the name of the process that is the parent of the session leader. For processes started within a terminal emulator, that would generally be the process running that terminal emulator (unless things like screen, expect, tmux... are being used (though note that screen and tmux are terminal emulators), or new sessions are started explicitly with setsid, start-stop-daemon...)

If you find nested parenthesis hard to read, you could write it on several lines:

ps -o comm= -p "$((
                  $(
                    ps -o ppid= -p "$((
                                      $(
                                        ps -o sid= -p "$$"
                                      )
                                    ))"
                  )
                ))"

Or use variables (which can also help make the script more self explanatory):

sid=$(ps -o sid= -p "$$")
sid_as_integer=$((sid)) # strips blanks if any
session_leader_parent=$(ps -o ppid= -p "$sid_as_integer")
session_leader_parent_as_integer=$((session_leader_parent))
emulator=$(ps -o comm= -p "$session_leader_parent_as_integer")

You could also try parsing wtmp where terminal emulators usually log an entry with their pid associated with the pseudo-terminal device. This works for me on a Debian system provided expect/screen/tmux... are not involved:

ps -o comm= -p "$(
  dump-utmp -r /var/log/wtmp |
  awk -v tty="$(ps -o tty= -p "$$")" -F ' *\\| *' '
    $2 == tty {print $5;exit}')"

(using dump-utmp from GNU acct).

  • +1 good answer, but I can’t help reminiscing on nested parentheses in English :D – Stan Strum Jan 17 '18 at 17:10
  • @Stan, see edit. – Stéphane Chazelas Jan 18 '18 at 9:12
2

To find the name of the terminal emulator used by the current shell, you could ask the X window system to give you the name of the window that the shell is currently visible in:

$ xwininfo -id $WINDOWID | awk '/^xwin/ { print $NF }'

This gives back the string "xterm" for me in XTerm, and "urxvt" when I run in Rxvt-unicode. The result will probably be different if you have the habit of changing the window title though, because that's what is being handed back to you here I think.

  • What if xwininfo is not available? – coffeMug Feb 19 '16 at 13:02
  • Well, what if pstree is not available or if it's incompatible with your original solution? (The -s flag on OpenBSD systems, for example, have different semantics). – Kusalananda Feb 19 '16 at 13:04
  • That is exactly the reason I was looking for something more portable! – coffeMug Feb 19 '16 at 13:07
  • 2
    That gives you the window's title which can be overridden at run time or in configuration, you could use eval "$(xprop -notype -id "$WINDOWID" 32i '=$0' _NET_WM_PID)"; ps -o comm= -p "$_NET_WM_PID" to get the process name instead. – Stéphane Chazelas Feb 19 '16 at 13:15
  • 2
    @cofferMug, xwininfo is a standard X command like xprop. If your system has X11 terminal emulators, it should have those commands. – Stéphane Chazelas Feb 19 '16 at 13:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.