Is there a portable way to do this?
On Linux, I can use ps a -N
but this option isn't available on other (POSIX) systems.
Of course I can use grep '^?' with, say, -o tty,... but is there something more reliable?
Is there a portable way to do this?
On Linux, I can use ps a -N
but this option isn't available on other (POSIX) systems.
Of course I can use grep '^?' with, say, -o tty,... but is there something more reliable?
Standard ps allows you to get information about all processes using its -A option, and to get specific information fields using -o.
The issue is that the way the TTY field's string is formatted may differ between systems. On Linux, a process with no controlling TTY will have its TTY reported as ?, while FreeBSD uses -, and both macOS and OpenBSD use ??.
So if you want to use the system's ps, you could possibly start by figuring out what to look for to identify a process without a terminal. You could potentially use ps -p 1 -o tty= for this, assuming PID 1 is an existing process without a controlling terminal. This ought to output ? on Linux, ?? on macOS and OpenBSD, and - on FreeBSD. In the command below, I'm also trimming off any blanks from the output of that ps command:
ps -A -o tty,pid | awk -v t="$(ps -p 1 -o tty=|tr -d '[:blank:]')" '$1 == t { print $2 }'
This should work in most places, except where PID 1 does not exist, and not on Busybox-based systems (since Busybox' implementation of ps does not have a -p option).