3

To monitor process creation I'd like to periodically write the last PID assigned by the kernel to any process on the system (not just processes created by the PID-monitoring program) with a time stamp to a file (using a daemon to avoid creating any extra processes). Any language would be fine, but I have a feeling this should be possible (even easy) in POSIX shell.

l0b0
  • 50,672
  • 41
  • 197
  • 360

2 Answers2

4

This saves the timestamp and last PID to file every second in Bash, using the ns_last_pid sysctl:

The last pid allocated in the current (the one task using this sysctl lives in) pid namespace.

old=""
while read < /proc/sys/kernel/ns_last_pid
do
    if [ "$REPLY" != "$old" ]
    then
        printf '%(%s)T %d\n' -1 "$REPLY"
        old=$REPLY
    fi
    read -t 1 || true
done > pids.log

Problems:

Grisha Levit
  • 304
  • 1
  • 7
l0b0
  • 50,672
  • 41
  • 197
  • 360
  • */proc/sys/kernel/ns_last_pid is not available everywhere.* Most notably, /proc is only available on Linux... – user May 14 '13 at 14:47
  • 1
    All the non-POSIX idioms in there have actually been borrowed by `bash` from the Korn shell. So it's not `bash` specific, its `ksh93/bash` specific. Note that `sleep` is builtin in `ksh93` and it also has a `cat` builtin (only enabled if `/opt/ast/bin` is before `/bin` (or wherever the system `cat` is) in `$PATH`). POSIX doesn't specify which commands are builtin. – Stéphane Chazelas May 14 '13 at 15:01
  • Odd, I don't have that file on several Linux boxes I checked, but they do have pid namespace support. One is even using namespaces... – derobert May 14 '13 at 15:38
  • That file doesn't exist on any Red Hat distros I have (Fedora 14,17 + CentOS 5,6). Ubuntu 12.10 has it. – slm May 14 '13 at 18:50
2

POSIX doesn't provide a way to get the last PID assigned by the kernel so there can't be a portable answer.

Here is a oneliner that should work on all systems implementing dtrace (Solaris, FreeBSD, NetBSD, Mac OS X, Oracle Linux with latest UEK, and others like Illumos based OSes, Linux with dtrace4linux)

# dtrace -qn 'proc:::exec-success { printf("%Y - %d\n",walltimestamp,pid); }'
2013 May 15 00:48:47 - 1276
2013 May 15 00:48:49 - 1277
2013 May 15 00:48:52 - 1278

Edit:

On Linux, an alternative would be to use systemtap if available with which this command (untested) should provide a similar output:

# stap -e 'probe syscall.execve { printf("%s - %d\n",ctime(gettimeofday_s()),pid()); }'
jlliagre
  • 60,319
  • 10
  • 115
  • 157
  • @l0b0 As I wrote, you need an OS with dtrace installed which is obviously not the case with your test machine. There are a couple of dtrace implementations with Linux: Oracle Linux 6.4 with UEK and dtrace4linux. You might also use systemtap. Answer updated. – jlliagre May 15 '13 at 09:19
  • @l0b0 Answer updated again, I'm still unsure about if pid need to be called as a function or used as a variable. – jlliagre May 15 '13 at 10:24
  • There's no syntax error anymore, but "missing x86_64 kernel/module debuginfo under '/lib/modules/3.5.0-27-generic/build' while resolving probe point kernel.function("do_execve").call". `apt-cache search debuginfo` doesn't reveal anything useful, so I guess this isn't possible on my distro. – l0b0 May 15 '13 at 10:53
  • @l0b0 Your question is tagged POSIX and as I wrote there cannot be a POSIX way to match your requirements. You'd rather tell what your distribution is. – jlliagre May 15 '13 at 12:27