Get all files open for writing with pid, recursively

lsofprocess

Given a pid, I can get all the files open for writing something like:

lsof -p 28827 | awk '$4 ~ "[wW]"{print $(NF-1), $NF}'

One of those ends up being a pipe:

28827 232611 pipe

I want to look-up all the files open by that pipe. If I just do:

lsof | grep 232611

That gives me a bunch of processes, one of which is a tee:

COMMAND     PID   TID    USER   FD      TYPE             DEVICE  SIZE/OFF    NODE NAME
<app>     28827       <me>       1w     FIFO                0,8       0t0  232611 pipe
<app>     28827 28836 <me>       1w     FIFO                0,8       0t0  232611 pipe
<app>     28827 28901 <me>       1w     FIFO                0,8       0t0  232611 pipe
....
tee       28828       <me>       0r     FIFO                0,8       0t0  232611 pipe

How can I programmatically find the PID for the tee (or generally, any process open with r access)? I can't simply check $4 ~ "r" since for most of the rows, $4 isn't even the FD column.

Best Answer

It should be enough to just grep for digits followed by one or more rs:

lsof | grep -P '\b\d+r+\b'

Or, if you don't have GNU grep:

lsof | grep -E '\b[0-9]+r+\b' 

The \bs mark word boundaries and ensure that only entire fields are matched. Alternatively, if your grep supports it, you can use the -w flag:

lsof | grep -wE '[0-9]+r+' 

So, using that, you can get the relevant PIDs with

lsof | grep -wE '[0-9]+r+' a | awk '{print $2}'

@derobert pointed out in the comments below that, had I taken the time to actually read through the 2562 lines of man lsof, I would have found that it offers an -F option that lets you choose the fields printed. To get the file's access type, use a:

lsof -p 28827 -F a 
Related Question