Grep and special files
Sometimes, you may wondering why a simple grep -R /my/path suddenly stalls, without any blatant reason nor disk activity.
First thing to do (after having nervously restarted the command of course ;-)) : check the process state with ps:
|
|
The STAT column is interesting here, because it gives the process status (man ps)
|
|
S means the process is waiting for something to happen, but not I/O related like I was expected, otherwise the state would have been D.
Before restarting the command through strace, let’s ps tell us more about the event our grep process is waiting for. Here is the waiting channel, or wchan.
Waiting channel
A waiting channel is the kernel function where the process is sleeping, waiting for its completion to resume (man ps):
|
|
Just ask ps to display this field:
|
|
pipe_w ? A first sight, pipe means the shell | character, used to stream and filter output through multiple commands. But I’ve launched a standalone grep command, not followed by any pipe, so wtf?
Just remember that the pipe concept is also hidden behind another computing concept: a FIFO, which is nothing else than a persistent pipe on the file system.
Things become clear: a leftover FIFO is somewhere in my tree, and grep is waiting for something to read. Finally, more details with strace:
|
|
grep is stuck on the /srv/tmp/.licq/licq_fifo file, waiting for data that will never come, since nothing is written to this FIFO.
However I wonder why openat() blocks, instead of issuing a subsequent read() syscall ?
Grep and FIFOs
Of course, this case is handled by grep, a quick glance to its manpage shows that its behavior can be tweaked regarding special files:
|
|
Finally, with this option my command works as expected:
|
|
I’m starting to consider to really read the manpage of each day-to-day commands I use, many gems are hidden !