0

There are many ways to obtain the PTS associated with a given process - such as using the tty command or resolving /proc/self/fd/0 (assuming it's open and not redirected) - but what about the inverse? How do I obtain the PID of the shell running the pts?

I can try to use something like ps -t $(tty) but this does not provide enough information to reliably determine the root shell (i.e. multiple shell instances, PID reuse on long running systems, etc). The only way I can think of to this is to manually collect all processes associated with the terminal and visit each process's /proc entry to determine process hierarchy and then assume it's the topmost parent process.

Is there a simple inverse tty command I can use? One that gives me the PID without too much work?

2
  • 1
    "visit each process's /proc entry to determine process hierarchy" ... Does ps -t $(tty) --forest help with that?
    – muru
    Aug 27 at 9:48
  • I assume it could if ps guarantees that the topmost process returned is also the root of the forest, but I'm unsure if there aren't any edge cases I should account for. If there's a proper way to query linux's tty subsystem, or have a link to it, it would be much more preferable. Aug 27 at 10:10

1 Answer 1

1

If your ps command supports sorting by the start time, you can find the earliest process that has this tty.

$ ps --sort start_time -t pts/138 |head -2
  PID TTY          TIME CMD
13326 pts/138  00:00:02 bash

If your ps doesn't support that, you can still get the pid of the earliest process with the tty by sorting all the relevant pids by their start time (the 22nd field in /proc/<pid>/stat - "The time the process started after system boot") and getting the pid with the lowest one:

$ for p in $(ps -o pid -t pts/138 |tail -n +2); do awk -v PID=$p '{print $22,PID}' /proc/$p/stat 2>/dev/null; done | sort -g | head -1 | awk '{print $2}'
13326

Or in a more readable way:

$ for p in $(ps -o pid -t pts/138 |tail -n +2)
do
  awk -v PID=$p '{print $22,PID}' /proc/$p/stat 2>/dev/null
done | sort -g | head -1 | awk '{print $2}'
13326 

You must log in to answer this question.

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