9

The *nix command lsof gives you a list of open files. Is anyone aware of a way that would also list how long a particular file has been open? Either by using lsof or any other command. I'm using CentOS 5.3 and unfortunately I can't install additional repositories so I'd have to work from the default CentOS repos.

Thanks

3
  • 1
    Why do you need that? I have currently no idea how to achieve that with either lsof or any other utils, so maybe there's an alternative solution to your problem...
    – plaes
    Jan 5, 2012 at 10:29
  • There's an (in house) application specific problem and one of our processes is keeping a file open, but I can't determine if it's doing this everytime it's called, therefore I'd like to see the age of each open file, i.e. file1 is open since 2012-01-01 00:00:00, file2 is open since 2012-01-02 00:00:00 etc.
    – Tamas
    Jan 5, 2012 at 10:34
  • 2
    There are two things I could think of: strace -e open,close program or valgrind with the --track-fds=yes option.
    – plaes
    Jan 5, 2012 at 10:39

3 Answers 3

3

If you have the pid, you can directly check in /proc/$pid/fd. It seems to be where file descriptors are created.

If you take a look at their creation date with a simple ls -lh, maybe you'll be able to know how long a particular file has been open.

1
0

A -- not very exact guess -- could be to use the pid provided by lsof and use ps to find out since when the program that opened the file is running. This is of course working only for files opened at program start, not for later opened files.

0

I tried to get this for myself. What I came up with is this:

#!/bin/sh

BASE=`basename "${0}" ".sh" `
TMP="/tmp/tmp.$$.${BASE}"

#COMMAND     PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
#firefox    2713      username   88u  IPv4 445702      0t0  TCP 192.168.0.10:42564->142.251.41.4:443 (ESTABLISHED)
#firefox    2713      username   94u  IPv4 445943      0t0  TCP 192.168.0.10:50416->108.138.106.67:443 (ESTABLISHED)
#firefox    2713      username  119u  IPv4  44675      0t0  TCP 192.168.0.10:49430->104.16.249.249:443 (ESTABLISHED)
#firefox    2713      username  144u  IPv4 275162      0t0  TCP 192.168.0.10:34266->34.218.164.174:443 (ESTABLISHED)

sudo lsof -Pni | grep '(ESTABLISHED)' >"${TMP}.connections"

cat "${TMP}.connections" |
awk '{
    ### fd/1 gives the timestamp of the last usage of stdin
    #printf("/proc/%s/fd/1|%s|%s|%s\n", $2, $4, $9, $10 ) ;

    ### mountinfo gives the timestamp when the [main] process was started.
    printf("/proc/%s/mountinfo|%s|%s|%s\n", $2, $4, $9, $10 ) ;
}' |
while [ true ]
do
    read line
    if [ -z "${line}" ] ; then exit 0 ; fi

    procpath=`echo "${line}" | awk -F \| '{ print $1 }' `
          fd=`echo "${line}" | awk -F \| '{ print $2 }' `
        conn=`echo "${line}" | awk -F \| '{ print $3 }' `
      status=`echo "${line}" | awk -F \| '{ print $4 }' `

    age=`stat "${procpath}" | grep '^Change' | awk '{ p=index( $3, "." ) ; time=substr( $3, 1, p-1 ) ; print $2, time ; }' `

    dat=`awk -v FD="${fd}" '{ if( $4 == FD ){ print $0 ; exit } ; }' "${TMP}.connections" `

    echo "${age}  ${dat}"
done

The output to that looks like this:

2022-09-18 16:16:33  firefox    2713      username   88u  IPv4 776358      0t0  TCP 192.168.0.10:39970->151.101.129.69:443 (ESTABLISHED)
2022-09-18 16:16:33  firefox    2713      username  119u  IPv4  44675      0t0  TCP 192.168.0.10:49430->104.16.249.249:443 (ESTABLISHED)
2022-09-18 16:16:33  firefox    2713      username  144u  IPv4 275162      0t0  TCP 192.168.0.10:34266->34.218.164.174:443 (ESTABLISHED)
2022-09-18 16:16:33  firefox    2713      username  161u  IPv4 547918      0t0  TCP 192.168.0.10:34960->198.252.206.25:443 (ESTABLISHED)
2022-09-18 16:16:33  firefox    2713      username  170u  IPv4 543499      0t0  TCP 192.168.0.10:33700->198.252.206.25:443 (ESTABLISHED)
2022-09-18 16:16:33  firefox    2713      username  187u  IPv4 549543      0t0  TCP 192.168.0.10:47142->198.252.206.25:443 (ESTABLISHED)

The problem with this is that the date is the same for all the firefox related items because is not reporting a different PID, even though ps does report multiple PIDs for various sub-tasks.

Don't know if that is something that the lsof people would see a benefit to work on.

Also, the FD values, such as "119u" are nowhere to be found under the /proc/2713 tree, neither as filename, nor as content in any of the files in that tree. I am definitely not an expert, but as a user, I would have imagined that there should be some concrete linkage between that "119u" and the fd items listed under the process tree.

You must log in to answer this question.