11

From the question here, the OP wants to repeatedly poll the pid of a process using pidof in a shell script. Of course this is inefficient as a new process must be started for the pidof program multiple times per second (I don't know that this is the cause of the CPU spikes in the question, but it seems likely).

Usually the way around this kind of thing in a shell script is to work with a single program that outputs the data you need on stdout and then doing some text processing if necessary. While this involves more programs to be running concurrently, it is likely to be less CPU intensive since new processes are not being continually created to for polling purposes.

So for the above question, one solution might be to have some program which outputs the names and pids of processes as they are created. Then you could do something like:

pids-names |
  grep some_program |
  cut -f 2 |
  while read pid; do
    process-pid "$pid"
  done

The problem with this is that it raises a more fundamental question, how can pids and process names be printed as they are created?

I have found a program called ps-watcher, though the problem with this is that it is just a perl script which repeatedly runs ps so it doesn't really solve the problem. Another option is to use auditd which could probably work if the log was processed directly via tail -f. An ideal solution would be simpler and more portable than this, though I will accept an auditd solution if it is the best option.

5
  • 1
    An interesting side note is that the pid is first created as a copy of the creating process (fork or variant), then the new program is started using a member of the exec family. So you probably want to log the exec*, not the fork.
    – derobert
    Oct 22, 2014 at 21:15
  • 2
    The only portable efficient way I'm aware of is to use ordinary Unix process accounting, which will write a record after a process exits. If you want to catch processes as they're created or execed, you probably need system-specific things such as Linux auditd, systemtap, or dtrace. Oct 22, 2014 at 21:21
  • So for the above question, one solution might be to have some program which outputs the names and pids of processes as they are created. – As they're created? Sounds what you're thinking of is an observer (this is what they call them in web browser world). I'm wondering if Python would be suitable for acting as a "door guard"? Facts are that Python can dig very deeply into the system's inner workings (e. g. dbus). Oct 22, 2014 at 22:04
  • 1
    @syntaxerror DBus is far from system's inner working in this case - it's actually about two levels above what is being discussed here.
    – peterph
    Oct 23, 2014 at 7:54
  • OK, in OSI lingo the tier discussed here might be still lower than that of dbus. I admit that I hadn't thought in-depth about whether both are on the same tier or not. Oct 23, 2014 at 16:40

2 Answers 2

6

Linux-specific answer:

perf-tools contains an execsnoop that does exactly this. It uses various Linux-specific features such as ftrace. On Debian, its in the perf-tools-unstable package.

Example of me running man cat in another terminal:

root@Zia:~# execsnoop 
TIME        PID   PPID ARGS
17:24:26  14189  12878 man cat 
17:24:26  14196  14189 tbl 
17:24:26  14195  14189 preconv -e UTF-8 
17:24:26  14199  14189 /bin/sh /usr/bin/nroff -mandoc -Tutf8 
17:24:26  14200  14189 less 
17:24:26  14201  14199 locale charmap 
17:24:26  14202  14199 groff -mtty-char -Tutf8 -mandoc 
17:24:26  14203  14202 troff -mtty-char -mandoc -Tutf8 
17:24:26  14204  14202 grotty 

I doubt there is a portable way to do this.

2

There Right WayTM of doing this depends heavily on what system and kernel you are actually running on. DTrace should work on Solaris, Free/NetBSD and Linux.

For Linux specifically, you can use either ftrace (which has to be enabled at compile time - it usually is) or proc events over netlink - see the SO answer to the problem for more details (and remember to vote it up, the score ~30 vs. 0 for accepted answer looks funny). Poor man's tracer could probably be implemented by using strace -eexec,fork (although with unreasonable overhead).

You must log in to answer this question.

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