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.
Asked
Active
Viewed 1,611 times
2 Answers
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:
/proc/sys/kernel/ns_last_pidis only available in Linux 3.3 and newer- The
printf%(fmt)Tspecifier is only available in Bash 4.2 and newer - POSIX
readdoesn't have the-toption. - Can't use
sleep,cator other non-builtins, since they would use additional PIDs.
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
-
1All 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