7

A file is locked with either a fcntl (non-blocking) or some custom way. So I'm using lsof and checking if pid of a process is in there. If lsof returns blank than nothing is using it.

However lsof from my script takes 200ms.

On windows when i try to test for if the file is locked i just open the file and on error its locked, this takes 5ms. Is there any alternative to lsof to do a quick test to see if something is got a hold of a file?

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
Noitidart
  • 35,443
  • 37
  • 154
  • 323
  • Thanks mans ill check that out and report back on speed :) – Noitidart Sep 22 '14 at 19:52
  • 1
    I added it as an answer, let me know if it solved ur issue. – z atef Sep 22 '14 at 20:21
  • 1
    `lsof` by default tries to resolve host names. `lsof -n` does not and is much faster. – Stéphane Gourichon Jun 27 '17 at 15:44
  • Thanks very much @StéphaneGourichon!! So I should use `lsof -n FILE` correct? to find open files? – Noitidart Jun 27 '17 at 22:19
  • 1
    @Noitidart My comment was only about the usual reason why `lsof` is slow in general. In any case, you should include in your question the command line where you used `lsof`. I just tried `touch /tmp/locked ; flock /tmp/locked -c "sleep 120"` in a terminal and `time lsof -F cl /tmp/locked` in another. Time reported is 0.074s. `-F cl` asks to output command name and lock status in a way that is somehow easier to parse from a caller script. – Stéphane Gourichon Jun 28 '17 at 08:07
  • 1
    If your lock times are shorter (you mention 30ms below), you should probably give up scripts and make a simple C program, or reconsider the whole point (perhaps http://xyproblem.info/ is relevant here). – Stéphane Gourichon Jun 28 '17 at 08:08
  • Thanks @StéphaneGourichon - my use case was to find what PID is locking a certain file. – Noitidart Jun 28 '17 at 16:59

2 Answers2

13

The fuser command is a very smart unix utility used to find which process is using a file, a directory or a socket. It also gives information about the user owning the process and the type of access. READ MORE --digitalocean.com

To show processes accessing a particular directory use :

fuser -uvm /somedir

The below output shows that, when ran in verbose mode, the fuse utility gives information about the USER, PID, ACCESS and COMMAND

root@exampleuser-X55CR:~# fuser -v .
                     USER        PID ACCESS COMMAND
/root:               root       3378 ..c.. vim
                     root       3398 ..c.. bash
                     root       3449 ..c.. bash
                     root      19370 ..c.. bash

fuser is useful in identifying process id opening a particular file.

lsof is useful to find out all file(s) opened by particular process.

for more options that go with fuser you can check thier man page man fuser

here is some :

]$ fuser
No process specification given
Usage: fuser [ -a | -s | -c ] [ -n SPACE ] [ -SIGNAL ] [ -kimuv ] NAME...
             [ - ] [ -n SPACE ] [ -SIGNAL ] [ -kimuv ] NAME...
       fuser -l
       fuser -V
Show which processes use the named files, sockets, or filesystems.

    -a        display unused files too
    -c        mounted FS
    -f        silently ignored (for POSIX compatibility)
    -i        ask before killing (ignored without -k)
    -k        kill processes accessing the named file
    -l        list available signal names
    -m        show all processes using the named filesystems
    -n SPACE  search in this name space (file, udp, or tcp)
    -s        silent operation
    -SIGNAL   send this signal instead of SIGKILL
    -u        display user IDs
    -v        verbose output
    -V        display version information
    -4        search IPv4 sockets only
    -6        search IPv6 sockets only
    -         reset options

  udp/tcp names: [local_port][,[rmt_host][,[rmt_port]]]
z atef
  • 7,138
  • 3
  • 55
  • 50
  • This was great it brought down the speed by 50ms compared to `lsof`!. However is there anything faster? Its still taking over 100ms and the functiosn that rely on this are happening within 30ms. – Noitidart Sep 22 '14 at 21:15
  • Also out of curiousity is there any flag that will make fuser print the process name like lsof. Lsof gives a bunch of other crap i just need pid and process name :) The -v didnt work :( – Noitidart Sep 22 '14 at 21:18
  • 1
    did you use it like this "fuser -v ." – z atef Sep 22 '14 at 22:28
  • yes sir it, but it still didnt resemble the output of ps. i did `fuser -v "/home/noi/Desktop/rawr.txt"` its no big. i was wondering if u can maybe also add to post something that can just see if something would have a pid using it, but not really bother about searching for any info and just return. i accepted answer though. im trying to get to 5ms on avg time. im thinking the fecthing of so much other data is leading to the 150ms maximum times. – Noitidart Sep 23 '14 at 00:35
  • I've trouble with piping `fuser` output to other commands like grep. It does not seem to use stdout normally. – PlasmaBinturong Feb 07 '20 at 14:26
0

To find all pids of processes that are using a file run this shell function that inspects the /proc directory

#!/bin/bash

set -o pipefail
shopt -s extglob

_lsof() {
   local f="${1}" \
       inum
   inum="$(ls -i "$(readlink -f "${f}")" 2> /dev/null )" && \
   ( find /proc/+([0-9])/fd -follow -inum ${inum%% *} 2> /dev/null || : ) | \
       cut -f 3 -s -d '/' | \
       sort -n -u | \
       grep -sxvF "1"
}

pids="$(_lsof "filename")" || \
  echo "file is not in use"