Search code examples
bashfile-descriptorlsof

Cannot see files opened by a process


I know I can use lsof -p or ls /proc//fd to lists the files open by a process.

However, my question is, lets suppose I have a bash script running which is accessing a certain file X.

When I run the bash script and do a lsof -p or ls /proc//fd, I see the bash script name as one of the file open by the process.

Is there anyway to list file X here or by any other way that will tell me that file X is been accessed here ?


Solution

  • Text-based adventure:

    $ cd "$(mktemp --directory)"
    $ touch input.txt
    $ cat > test.sh <<EOF
    > #!/usr/bin/env bash
    > tail -f input.txt
    > EOF
    $ chmod u+x test.sh
    $ ./test.sh &
    [1] 921
    $ ps --forest -g $(ps -o sid= -p $!) w
      PID TTY      STAT   TIME COMMAND
      574 pts/4    Ss     0:00 bash
      921 pts/4    S      0:00  \_ bash ./test.sh
      927 pts/4    S      0:00  |   \_ tail -f input.txt
      984 pts/4    R+     0:00  \_ ps --forest -g 574 w
    

    So you can see that when you run a script which contains a command which reads a file there are actually three processes involved: the interactive Bash session and its descendants, the script, and the command in the script (plus the ps we just ran).

    So if you want to know about files used by the script you either have to get to the files with at least one ps command. But if you instead just want to know which program is accessing a specific file you can ask lsof directly:

    $ lsof input.txt 
    COMMAND PID          USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
    tail    927      username    3r   REG   0,45        0 2047211 input.txt