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
...)
Or breaking it down into individual steps using 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")
The stripping of whitespace around numbers here is done using $((...))
arithmetic expansion. You could also doing it using the split+glob operator (assuming an unmodified $IFS
) or as suggested by @ack in comments using xargs
:
ps -o sid= -p "$$" |
xargs ps -o ppid= -p |
xargs ps -o comm= -p
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
).
xterm
,rxvt
etc.) or the terminal device (/dev/pts/23
,/dev/ttyp3
etc.)? – Kusalananda Feb 19 '16 at 12:33ps -p $(ps -h -o ppid -p $$) -o cmd
. – Arcticooling Nov 15 '17 at 13:52ssh
session from a different machine, or even someone logged on to one of the non-graphic ttys. – Chris Davies Sep 07 '20 at 17:31