Identify processes using files or sockets through Linux fuser command

By | 18/02/2013

For a Linux user, fuser is an efficacious utility. It stands for file user and as it suggests, it tells us the processes which are using the file. In this article we will study when and how to use Linux fuser command through practical scenarios and examples. Since in Linux everything is a file, we shall see later in the article, how it is used for directories and sockets too.

To get familiar with Linux fuser command syntax, here is how it is normally used:

$fuser [option(s)] <name-of-file>

To elaborate on the detailed usage, here is a snapshot taken from its help information:

$ fuser -h
Usage: fuser [-fMuv] [-a|-s] [-4|-6] [-c|-m|-n SPACE] [-k [-i] [-SIGNAL]] NAME...
   	fuser -l
   	fuser -V
Show which processes use the named files, sockets, or filesystems.

  -a,--all          	display unused files too
  -i,--interactive  	ask before killing (ignored without -k)
  -k,--kill         	kill processes accessing the named file
  -l,--list-signals 	list available signal names
  -m,--mount        	show all processes using the named filesystems or block device
  -M,--ismountpoint 	fulfill request only if NAME is a mount point
  -n,--namespace SPACE  search in this name space (file, udp, or tcp)
  -s,--silent       	silent operation
  -SIGNAL           	send this signal instead of SIGKILL
  -u,--user         	display user IDs
  -v,--verbose      	verbose output
  -w,--writeonly    	kill only processes with write access
  -V,--version      	display version information
  -4,--ipv4         	search IPv4 sockets only
  -6,--ipv6         	search IPv6 sockets only
  -                 	reset options

  udp/tcp names: [local_port][,[rmt_host][,[rmt_port]]]

All the usage options are self explanatory from the help output, however we shall illustrate more through examples. However, note some of the options like ‘-k’ which is used to kill a process and ‘-SIGNAL’ which is used to send a signal. Therefore fuser command can be used to kill a process and send signals also.

 

Linux fuser command examples

Some practical scenarios

To answer the question – where shall we use this ‘fuser’ utility, I am listing a few example scenarios:

  • You are about to unmount a file system, and you get device busy as an error. To analyse, what could be causing the issue, a plausible reason could be a file being used. And hence, fuser command will help resolve the problem by listing all processes, if any using the file system. Not only file system, Linux fuser command will help determine the process/user accessing any socket or even a device.
  • In a multi-threaded environment, if a thread somewhere closes a file, which might be used by another thread later on, introduces a bug. Such bugs can be easily caught using Linux fuser command.
  • The fuser command can also be used to force delete a file (that is already being used), by killing all processes accessing the file. However, it depends on the user’s requirement and circumstances to force delete a file. Generally, it is not a recommended action though.

Now lets understand the usage of this command through some examples.

Example 1- Process accessing a file

To illustrate the usage of Linux fuser command, we need a process which is in running state and using a file. As a C  programmer, it is pretty convenient to write and run an executable that opens a file and retain it for some time. Following is the C source, where we open an existing file on disk in read-only mode, and sleep for some time, following which we close the file. The file would be in-use for the entire time since it has been opened and till it has been closed.

#include <stdio.h>
#include <unistd.h>

int main()
{

	FILE *fp = NULL;
	fp = fopen("test.txt", "r");
	sleep(120);

	fclose(fp);
	return 0;
}

Further lets compile and get the executable running to have a process running and using the file ‘test.txt’ for a while.

$ gcc fusertest.c -Wall -o fusertest
$./fusertest &

Let us now quickly check the current running process to know the PID of our newly triggered process.

$ps
  PID TTY          TIME CMD
 3036 pts/1    00:00:00 fusertest
 3037 pts/1    00:00:00 ps
10077 pts/1    00:00:02 bash
18628 pts/1    00:03:39 gedit

Note the first line of the ‘ps’ command output. Our executable name is the command and the PID is 3036.

Moving ahead, to use the Linux fuser command, let us now see and verify what all processes that are using the file ‘test.txt’. Please make sure, the user runs ‘fuser’ utility within 120 seconds i.e. 2 minutes of running the executable. In case, one wants more time, raise the sleep time as per the convenience.

Here is how we run the ‘fuser’ utility for ‘test.txt’.

$ fuser -v test.txt 
                     USER        PID ACCESS COMMAND
test.txt:            rupali    3036 f.... fusertest

First of all, have a look at the PID, it equals ‘3036’ and name of the command i.e. ‘fusertest’ in the output. It is the same as our triggered executable, verifying our demonstration to illustrate what ‘fuser’ does.

To understand more on the output, under ‘ACCESS’ column it has something like

f....

This means, the type of access is a file open. The various types of access are:

              c     -		current directory.

              e     -		executable being run.

              f      -		open file. f is omitted in default display mode.

              F      -		open file for writing. F is omitted in default display mode.

              r      -		root directory.

              m      -	mmaped file or shared library.

Note that, we use ‘-v’ option to get a verbose output. However, if we are interested in just the PID, one can omit the ‘-v’ option while using ‘fuser’.

$ fuser test.txt 
test.txt:             3036

Hence, we have now seen and learnt how we can determine all the processes accessing a particular file.

Example 2 – Process accessing a directory

Since a directory is also a file in Linux, we can use ‘fuser’ to identify processes accessing a particular directory. As an example, let us experiment using fuser command with our current directory. First we run our executable again, and then the utility fuser.

$ ./fusertest &
[2] 3345

$ fuser -v ./
                     USER        PID ACCESS COMMAND
./:                  rupali    3345 ..c.. fusertest
                     rupali   10077 ..c.. bash

The output displays for the current directory, which is being accessed by two processes, both by the same user ‘rupali’ but of different PID’s i.e. 3345, the fusertest executable and 10077, bash. The type of access in both cases is

..c..

which means the current directory. Hence, this implies that the directory which we gave as input to the ‘fuser’ utility is accessed as the current directory in two of these processes.

Example 3 – Process accessing a file system

The fuser command provides us with a ‘-m’ option, this option requires a file name to passed as input argument. All processes accessing files on the files system (of the input file) is displayed in output.
For example, try

$ fuser -m -v test.txt

This will list all the processes, which are accessing files present on the file system on which ‘test.txt’ resides. In my case, I get a huge list, here is a snapshot of it:

                     USER        PID ACCESS COMMAND
test.txt:            root     kernel mount /
                     rupali    1760 .rce. nxnode
                     rupali    1784 Frce. nxagent
                     rupali    1824 frce. nxnode
                     rupali    1834 Frce. ck-launch-sessi
                     rupali    1950 Frce. x-session-manag
                     rupali    1953 .rce. dbus-launch
                     rupali    1954 .rce. dbus-daemon
                     rupali   24763 .rce. mission-control
                     rupali   24768 Frce. bonobo-activati
                     rupali   24781 Frce. wnck-applet
                     rupali   24783 Frce. trashapplet
                     rupali   24786 Frce. indicator-apple
                     rupali   24788 Frce. notification-ar
                     rupali   24790 .rce. gvfsd-burn
                     rupali   24801 Frce. gvfsd-metadata
                     rupali   26243 Frce. nautilus
                     rupali   26244 Frce. bluetooth-apple
                     rupali   26245 Frce. nm-applet
                     rupali   26256 Frce. vino-server
                     rupali   26257 Frce. evolution-alarm
                     rupali   26258 Frce. tint2
                     rupali   26263 Frce. gnome-power-man
                     rupali   26264 Frce. polkit-gnome-au
                     rupali   26277 Frce. notify-osd
                     rupali   26280 .rce. mission-control
                     rupali   26290 Frce. gnome-screensav
                     rupali   26292 .rce. gvfsd-trash
                     rupali   26293 Frce. gdu-notificatio
                     rupali   26300 .rce. gvfsd-burn
                     rupali   26306 .rce. dconf-service
                     rupali   26318 Frce. sh
                     rupali   26319 Frce. unity-window-de
                     rupali   26322 frce. bamfdaemon
                     rupali   26333 Frce. gvfsd-metadata
                     rupali   26336 Frce. unity-panel-ser
                     rupali   26349 Frce. indicator-sessi
                     rupali   26351 Frce. indicator-me-se
                     rupali   26356 Frce. indicator-datet
                     rupali   26359 .rce. indicator-sound
                     rupali   26380 Frce. geoclue-master
                     rupali   26388 .rce. indicator-appli
                     rupali   26390 .rce. indicator-messa
                     rupali   26402 Frce. applet.py
                     rupali   26412 Frce. ubuntuone-syncd
                     rupali   26436 Frce. update-notifier
                     rupali   26452 Frce. update-manager
                     rupali   26476 Frce. unity-applicati
                     rupali   26496 .rce. unity-files-dae
                     rupali   32356 .rce. bash

We need to know the processes accessing a file system, in situations where we need to unmount a filesystem, and are not able to due to some process accessing it. The Linux fuser command will come to rescue in such cases, to identify and kill those processes.

Example 4 – Process accessing a network port

While working on or resolving network issues, it is very useful to know what all ports are busy and are being used by which processes. The ‘fuser’ utility also assists in knowing the same for tcp and udp ports. As an example, here is how we get to know processes using a tcp port:

$ fuser -v -n tcp 22

It may give no output in your case depending upon any process using tcp port 22 or not. One can know the active ports on a Linux system through the netstat command. Here is the netstat command along with a sample output snippet on my system.

$ netstat -antu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
…
…
…
tcp        9      0 127.0.0.1:5008          127.0.0.1:40713         ESTABLISHED
tcp     7570      0 192.168.1.72:49844      69.59.197.29:443        CLOSE_WAIT 
…
…
…

So from the ‘netstat’ output above, we see TCP ports 5008 and 49844 being used by some process. What are those processes, let us run following command,

$ fuser -n tcp 5008
5008/tcp:             1784
$ fuser -n tcp 49844
49844/tcp:           18647

The output identifies the PID of processes, however again if we would like to see a detailed output, ‘-v’ option is the key,

$ fuser -v -n tcp 49844
                     USER        PID ACCESS COMMAND
49844/tcp:           rupali   18647 F.... firefox

Just see how easily it was known that Firefox was using that port.

Example 5 – To kill processes

Not only fuser command comes in handy to identify the processes, it can also be used to kill the identified processes if need be. The processes identified can be killed by using ‘-k’ option.

Here is a demonstration, which first runs a process accessing a file, and then list the running processes and finally killing the processes which are using the file. In the end, we again check the list of running processes to verify if the relevant process has been killed.

$ ./fusertest &
[2] 3544
$ ps
  PID TTY          TIME CMD
 3544 pts/1    00:00:00 fusertest
 3545 pts/1    00:00:00 ps
10077 pts/1    00:00:03 bash
18628 pts/1    00:03:40 gedit

$ fuser -v -k test.txt 
                     USER        PID ACCESS COMMAND
test.txt:            rupali    3544 F.... fusertest
[2]+  Killed                  ./fusertest

$ ps
  PID TTY          TIME CMD
 3547 pts/1    00:00:00 ps
10077 pts/1    00:00:03 bash
18628 pts/1    00:03:40 gedit

It is worth mentioning that ‘fuser’ does not ask for any confirmation before killing a process. The command given is the command executed. In case, there are a number of processes using this file, all the processes would be killed.

However, we do have an option to kill the processes interactively. This means the user is prompted at run time to confirm whether a particular action is to be taken or not. The option is ‘-i’. Here is the sample usage:

$ fuser -v -k -i test.txt 
                     USER        PID ACCESS COMMAND
test.txt:            rupali    3548 F.... fusertest
Kill process 3548 ? (y/N) y
[2]+  Killed                  ./fusertest

Note that line (in bold) above. The fuser command asked the user whether to kill process 3548 or not.

A sample usage, where we have more than one process to be killed:

$ fuser -v -k -i ./
                     USER        PID ACCESS COMMAND
./:                  rupali    3553 ..c.. fusertest
                     rupali   10077 ..c.. bash
Kill process 3553 ? (y/N) y
[2]+  Killed                  ./fusertest
Kill process 10077 ? (y/N) n

This way multiple actions can be done interactively.

Example 6 – Sending signals to processes

To add to the bucket of whole lot of capabilities, ‘fuser’ can also be used to send specific signals to processes. When we kill the process through ‘-k’ option, we are internally sending a ‘KILL’ signal to the process. First of all, what are the kinds of signals which can be sent to a running process. Here is how we get the list:

$ fuser -l
HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM
STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS
UNUSE

To send a signal, ‘fuser’ offers ‘-SIGNAL’ option, along with ‘-k’. The difference is, here now since what kind of signal to be sent is mentioned, so the mentioned signal will be sent to the concerned processes. In case, no signal is mentioned, by default ‘KILL’ signal is sent.

$ fuser -v -ki -SIGSTOP test.txt
                 	USER    	PID ACCESS COMMAND
/home/rupali/aprograms/test.txt:
                 	rupali  24140 f.... fusertest
Kill process 24140 ? (y/N) y

[4]+  Stopped             	./fusertest

With the stop signal, the process is now in the stopped state. To confirm, run the following Linux ps command

$ ps aux | grep fusertest
rupali 24140  0.0  0.0   2136   284 pts/2	T	15:00   0:00 ./fusertest
rupali 24974  0.0  0.0   4388   828 pts/2	S+   15:09   0:00 grep --color=auto fusertest

The process state is specified by the 8th column i.e. ‘T’, which signifies the state code for a stopped process.

Conclusion

This article helps to understand more about where and how to use the ‘fuser’ utility. However, generally it is a great tool under the umbrella of many such tools to provide information about processes and file system. In any eco-system, it is never just one tool which will do the wonders in finding and resolving an issue. If you note, in many of the examples above, I’ve used ‘ps’ command and ‘netstat’ command. There are many more linux utilities which can be used along with each other to develop big software and resolve even bigger issues. Therefore, in the end, I would say, since now we know yet another powerful Linux tool, we are one step closer to working on Linux efficiently.

NOTE : To learn more command line tools, read our articles on Linux netcat and strace commands

8 thoughts on “Identify processes using files or sockets through Linux fuser command

  1. David Ramirez

    Great tutorial, thanks for sharing the knowledge!
    I am trying to use this command to detect if a file being exported via NFS is open. So far, it seems to fail doing this. On a file being accessed (with an editor) from an external server, via a NFS share, if I stand on the shared directory and issue fuser (tested with several of its options), nothing is listed.
    Any ideas on this ?
    Thanks

    Reply
    1. Rupali

      Hi David,

      We are glad you found the article useful.
      Coming to the issue you are facing, I think fuser should be able to list processes using an file exported via NFS. One reason I can think of causing this issue is the connection, if it has gone stale due to something. Can you try remounting?
      If this is not the culprit, then can you please share your linux flavor, distribution and such details. That will really help us figure out the real cause.

      Reply
  2. Anuj Khanna

    Thanks for sharing this :),

    I was looking for the “command” to identify directory in use. Is there any command like that?

    using fuser i can get only file in use not directory

    hostserver(oracle:DBInstance)/opt/oracle/product: fuser /opt/oracle/product/12.1.0.1.AGT/core/12.1.0.3.0/perl/bin/perl
    /opt/oracle/product/12.1.0.1.AGT/core/12.1.0.3.0/perl/bin/perl: 18139tm
    hostserver(oracle:DBInstance)/opt/oracle/product:
    hostserver(oracle:DBInstance)/opt/oracle/product: fuser /opt/oracle/product/12.1.0.1.AGT/core/12.1.0.3.0/perl/bin
    /opt/oracle/product/12.1.0.1.AGT/core/12.1.0.3.0/perl/bin:
    hostserver(oracle:DBInstance)/opt/oracle/product:

    Background : I am naive in in Linux/Unix

    Regards

    Reply
      1. Anuj Khanna

        Yes,
        I tried but failed – My system is SunOS

        hostserver(oracle:NONE)/opt/oracle/product/DB1/bin: ps -ef|grep /opt/oracle|grep -i LISTENER
        oracle 18810 18809 0 04:33:04 ? 0:12 /opt/oracle/product/DB2/bin/rman msglog ‘/nsr/applogs/DB2_db2_ms
        oracle 23603 23588 0 12:13:47 ? 0:21 /opt/oracle/product/DB1/bin/rman msglog ‘/nsr/applogs/DB1_full_msglog
        oracle 6631 1 0 Sep 15 ? 28:29 /opt/oracle/product/12.1.0.1.AGT/core/12.1.0.2.0/perl/bin/perl /opt/oracle/prod
        hostserver(oracle:NONE)/opt/oracle/product/DB/bin: fuser -v ./
        fuser: illegal option — v
        Illegal option ?.
        Usage: fuser [-[k|s sig]un[c|f|d]] files [-[[k|s sig]un[c|f|d]] files]..
        hostserver(oracle:NONE)/opt/oracle/product/DB1/bin: fuser ./
        ./: 23527c 14113c
        hostserver(oracle:NONE)/opt/oracle/product/DB1/bin: ps -ef|grep 23527
        oracle 23759 14113 0 04:36:41 pts/13 0:00 grep 23527
        hostserver(oracle:NONE)/opt/oracle/product/DB1/bin: uname
        SunOS

        Reply
        1. Himanshu Arora

          I am not sure but it seems like your version of fuser command does not support -v option, which is for verbose output. Can you please cross check by reading the man page of this command on your system?

          Also, what I can see from the last part of the output is :

          The command ‘fuser ./’ produces ‘./: 23527c 14113c’ output. Aren’t these the PIDs of the processes you are looking for?

          Reply
          1. Anuj Khanna

            I checked man fuser and it is not supported :-

            >>> not supported
            hostserver1(oracle:NONE)/opt/oracle/product/12.1.0.1.AGT/core/12.1.0.3.0/perl/bin: uname -a
            SunOS hostserver1 5.10 Generic_148888-03 sun4u sparc SUNW,Sun-Fire-V490
            hoatserver2(oracle:NONE)/apps/oracle: uname -a
            SunOS hostserver2 5.10 Generic_147147-26 sun4u sparc SUNW,Sun-Fire-15000

            >>> -v is not but-V is supported
            $ uname -a
            AIX hostserver3 1 6 00F84D804C00

            but this too giving unwanted result :-
            $ ps -ef|grep /opt/oracle/product
            oracle 5374132 1 0 Aug 13 – 2:06 /opt/oracle/product/12.1.0.1.AGT/core/12.1.0.2.0/perl/bin/perl /opt/oracle/product/12.1.0.1.AGT/core/12.1.0.2.0/bin/emwd.pl agent /apps/oracle/product/12.1.0.1.AGT/agent_inst/sysman/log/emagent.nohup

            $ cd /opt/oracle/product/12.1.0.1.AGT/core/12.1.0.2.0/perl/bin
            $ pwd
            /opt/oracle/product/12.1.0.1.AGT/core/12.1.0.2.0/perl/bin
            $ fuser ./
            ./: 10158198c >>>>>> wrong one it should be 5374132

            Not sure whats wrong :P

  3. Anuj Khanna

    correcting last command above

    $ fuser -V ./
    ./:
    10158198c

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *