Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794
{"id":2877,"date":"2019-12-27T06:55:17","date_gmt":"2019-12-27T06:55:17","guid":{"rendered":"https:\/\/support.aklwebhost.com\/?post_type=manual_kb&p=2877"},"modified":"2019-12-27T06:55:17","modified_gmt":"2019-12-27T06:55:17","slug":"introduction-to-lsof","status":"publish","type":"manual_kb","link":"https:\/\/support.aklwebhost.com\/knowledgebase\/introduction-to-lsof\/","title":{"rendered":"Introduction to Lsof"},"content":{"rendered":"

Under Linux, many objects are considered a file, regardless of whether the object is actually a file, device, directory, or socket. Listing a file is easy, there is the shell built-in\u00a0ls<\/code>\u00a0for that. But what if a user wanted to see which files are currently opened by the web server process? Or if that user wanted to find out which files are opened in a certain directory? That’s where\u00a0lsof<\/code>\u00a0comes into play. Imagine\u00a0lsof<\/code>\u00a0as a\u00a0ls<\/code>\u00a0with the addition of “open files”.<\/p>\n

Please note that while the BSD’s have a different utility for this job,\u00a0fstat<\/code>, several other flavors of Unix (Solaris, for example) also possess\u00a0lsof<\/code>. The options and flags are different on the other platforms, as well as the look of the output, but generally the knowledge in this article should be applicable for them too.<\/p>\n

First, let’s take a look at the format of\u00a0lsof<\/code>\u00a0output and how it is to be read. The usual output of\u00a0lsof<\/code>\u00a0without any parameters would resemble the following. This has been trimmed for readability.<\/p>\n

COMMAND    PID  TID       USER   FD      TYPE             DEVICE  SIZE\/OFF       NODE NAME\r\ninit         1            root  cwd       DIR              254,1      4096          2 \/\r\ninit         1            root  rtd       DIR              254,1      4096          2 \/\r\ninit         1            root  txt       REG              254,1     36992    7077928 \/sbin\/init\r\ninit         1            root  mem       REG              254,1     14768    7340043 \/lib\/x86_64-linux-gnu\/libdl-2.13.so\r\ninit         1            root  mem       REG              254,1   1603600    7340040 \/lib\/x86_64-linux-gnu\/libc-2.13.so\r\ninit         1            root  mem       REG              254,1    126232    7340078 \/lib\/x86_64-linux-gnu\/libselinux.so.1\r\ninit         1            root  mem       REG              254,1    261184    7340083 \/lib\/x86_64-linux-gnu\/libsepol.so.1\r\ninit         1            root  mem       REG              254,1    136936    7340037 \/lib\/x86_64-linux-gnu\/ld-2.13.so\r\ninit         1            root   10u     FIFO               0,14       0t0       4781 \/run\/initctl\r\n<\/code><\/pre>\n

These columns mean the following:<\/p>\n

    \n
  • COMMAND – The process that an open file belongs to, in this example everything is related to\u00a0init<\/code>.<\/li>\n
  • PID – The process identification number of said process.<\/li>\n
  • USER – The user that the process runs under. For\u00a0init<\/code>, it’s almost always\u00a0root<\/code>.<\/li>\n
  • FD – The file descriptor of the file, the most common being:\n
      \n
    • cwd<\/code>\u00a0– The current working directory (you might notice the similarity to the\u00a0pwd<\/code>\u00a0command which prints the current working directory).<\/li>\n
    • rtd<\/code>\u00a0– The root directory of a process.<\/li>\n
    • txt<\/code>\u00a0– A\u00a0text file<\/code>, this can either mean a configuration file related to the process or the “source code” related to (or belonging to) the process.<\/li>\n
    • mem<\/code>\u00a0– A so called “memory mapped file”, that means a segment of virtual memory (read: RAM) that has been assigned to a file.<\/li>\n
    • A number – the number represents the actual file descriptor, the character after the number is the mode in which the file is opened:<\/li>\n
    • r<\/code>\u00a0– Read.<\/li>\n
    • w<\/code>\u00a0– Write.<\/li>\n
    • u<\/code>\u00a0– Read and write.<\/li>\n<\/ul>\n<\/li>\n
    • TYPE – Specifies the actual type of the file, the most common are:\n
        \n
      • REG<\/code>\u00a0– A regular file.<\/li>\n
      • DIR<\/code>\u00a0– A directory.<\/li>\n
      • FIFO<\/code>\u00a0– First in, first out.<\/li>\n<\/ul>\n<\/li>\n
      • DEVICE – The major and minor number of the device that holds the file.<\/li>\n
      • SIZE – The size of the file, in bytes.<\/li>\n
      • NODE – The inode number of the file.<\/li>\n
      • NAME – The name of the file.<\/li>\n<\/ul>\n

        This might be a little bit overwhelming for now, but if you work with\u00a0lsof<\/code>\u00a0a few times, it will quickly sink into your brain.<\/p>\n

        As mentioned above, the output of\u00a0lsof<\/code>\u00a0has been shortened here. Without any arguments or filters,\u00a0lsof<\/code>\u00a0produces hundreds of lines of output which will only leave you confused.<\/p>\n

        There are two basic approaches to solve that problem:<\/p>\n

          \n
        • Use one or more of the\u00a0lsof<\/code>\u00a0command line options to narrow down the results.<\/li>\n
        • Pipe the output through, for example,\u00a0grep<\/code>.<\/li>\n<\/ul>\n

          While the latter option may sound more comfortable since you won’t have to memorize the\u00a0lsof<\/code>\u00a0command line options, it’s generally not as flexible and efficient, so we’ll stick to the first one.<\/p>\n

          Let’s imagine that you want to open a file with your favorite text editor, and that the text editor tells you that it can only be opened in read-only mode because another program is already accessing it.\u00a0lsof<\/code>\u00a0will help you find out who the perpetrator is:<\/p>\n

          lsof \/path\/to\/your\/file\r\n<\/code><\/pre>\n

          This will produce an output similar to this:<\/p>\n

          COMMAND   PID USER   FD   TYPE DEVICE SIZE\/OFF    NODE NAME\r\nvim 2679 root    5w   REG  254,1   121525 6035622 \/root\/lsof.txt\r\n<\/code><\/pre>\n

          Apparently, you forgot to close and older session! A very similar problem happens when you try to unmount an NFS share and\u00a0umount<\/code>\u00a0tells you it can’t because something is still accessing the mounted folder. Again,\u00a0lsof<\/code>\u00a0can help you with identifying the culprit:<\/p>\n

          lsof +D \/path\/to\/your\/directory\/\r\n<\/code><\/pre>\n

          Notice the trailing slash, that’s important. Otherwise\u00a0lsof<\/code>\u00a0will assume you mean a regular file. Don’t be confused by the\u00a0+<\/code>\u00a0in front of the flag –\u00a0lsof<\/code>\u00a0has so many command line options that it needs\u00a0+<\/code>\u00a0in addition to the more common\u00a0-<\/code>. The output would look like this:<\/p>\n

          COMMAND  PID USER   FD   TYPE DEVICE SIZE\/OFF      NODE NAME\r\nmocp    5637  music    4r   REG   0,19 10147719 102367344 \/home\/Music\/RMS_GNU_SONG.ogg\r\n<\/code><\/pre>\n

          That means that the process\u00a0mocp<\/code>, with the PID\u00a05637<\/code>, belonging to the user\u00a0music<\/code>\u00a0has opened a file called\u00a0RMS_GNU_SONG.ogg<\/code>. However, even after closing that process, there is still a problem – the NFS volume can’t be unmounted.<\/p>\n

          lsof<\/code>\u00a0has a\u00a0-c<\/code>\u00a0flag that displays files opened an arbitrary process name.<\/p>\n

          lsof -c mocp\r\n<\/code><\/pre>\n

          That would produce an output looking like this:<\/p>\n

          mocp    9383  music    4r   REG   0,19 10147719 102367344 \/home\/Music\/ANOTHER_RMS_GNU_SONG.ogg\r\n<\/code><\/pre>\n

          In this example, there is another instance of\u00a0mocp<\/code>\u00a0running, preventing you from unmounting the share. After shutting down that process, you want to make sure that the user\u00a0music<\/code>\u00a0has no other potentially problematic files open.\u00a0lsof<\/code>\u00a0has a\u00a0-u<\/code>\u00a0flag for showing files opened by a specific user. Remember, a file isn’t always just a regular file on your hard disk!<\/p>\n

          lsof -u music\r\n<\/code><\/pre>\n

          You can also pass several users, separated by commas:<\/p>\n

          lsof -u music,moremusic\r\n<\/code><\/pre>\n

          An\u00a0important<\/strong>\u00a0note on the default behavior of\u00a0lsof<\/code>: the results are\u00a0OR<\/strong>-based, which means that you will see file results opened by processes that are owned by either the user\u00a0music<\/code>, or the user\u00a0moremusic<\/code>. If you wanted to see results matching processes that are owned by both users, then you would have to pass the flag\u00a0-a<\/code>:<\/p>\n

          lsof -au music, moremusic\r\n<\/code><\/pre>\n

          Since both of the users are in the group\u00a0musicusers<\/code>, then you can also list files based on group:<\/p>\n

          lsof -g musicusers\r\n<\/code><\/pre>\n

          You can also combine command line flags:<\/p>\n

          lsof -u music,moremusic -c mocp\r\n\r\nor\r\n\r\nlsof -u ^music +D \/home\/Music\r\n<\/code><\/pre>\n

          In the last line, we added another special flag –\u00a0^<\/code>, which stands for a logical\u00a0NOT<\/strong>. If the output is empty after running that command, then the unmounting will most likely be successful.<\/p>\n

          In the previous examples, we mostly looked at regular files. How about sockets and network connections?<\/p>\n

          To list\u00a0all<\/strong>\u00a0current network connections\u00a0lsof<\/code>\u00a0has the\u00a0-i<\/code>\u00a0flag:<\/p>\n

          lsof -i\r\n<\/code><\/pre>\n

          The output looks similar to what we’ve seen so far…<\/p>\n

          COMMAND    PID USER   FD   TYPE DEVICE SIZE\/OFF NODE NAME\r\nowncloud  3509  myuser   25u  IPv4  44946      0t0  TCP strix.local:34217->myserver.aklwebhost.com:https (ESTABLISHED)\r\nfirefox   3612  myuser   82u  IPv4  49663      0t0  TCP strix.local:43897->we-in-f100.1e100.net:https (ESTABLISHED)\r\nssh       3784  myuser    3u  IPv4  10437      0t0  TCP strix.local:51416->someserver.in:ssh (ESTABLISHED)\r\nwget      4140  myuser    3w  IPv4  45586      0t0  TCP strix.local:54460->media.ccc.de:http (CLOSE_WAIT)\r\n<\/code><\/pre>\n

          … except for one difference: instead of file names or directories, the column\u00a0NAME<\/code>\u00a0now shows connection information. Each connection consists of the following parts:<\/p>\n

            \n
          • Protocol.<\/li>\n
          • Local hostname.<\/li>\n
          • Source port of the connection.<\/li>\n
          • Destination DNS name.<\/li>\n
          • Destination port.<\/li>\n
          • Status of the connection.<\/li>\n<\/ul>\n

            As with many other tools, you may opt-out of resolving DNS names and ports (-n<\/code>\u00a0and\u00a0-P<\/code>, respectively). The flag\u00a0-i<\/code>\u00a0takes additional parameters. You can specify whether or not to show\u00a0tcp<\/code>,\u00a0udp<\/code>\u00a0or\u00a0icmp<\/code>\u00a0connections or certain ports:<\/p>\n

            lsof -i :25\r\nor\r\nlsof -i :smtp\r\n<\/code><\/pre>\n

            Again, parameters can be combined. The following example…<\/p>\n

            lsof -i tcp:80\r\n<\/code><\/pre>\n

            … will only show you TCP connections using port 80. You may also combine it with the options that you already know from “classic” files:<\/p>\n

            lsof -a -u httpd -i tcp\r\n<\/code><\/pre>\n

            This will show you all TCP connections opened by the user\u00a0httpd<\/code>. Note the\u00a0-a<\/code>\u00a0flag, which changes the default behavior of\u00a0lsof<\/code>\u00a0(as mentioned earlier). As with most command-line tools, you can go extremely deep. The following will only show you TCP connections whose state is “ESTABLISHED”:<\/p>\n

            lsof -i -s TCP:ESTABLISHED\r\n<\/code><\/pre>\n

            At this point, you should have a basic understanding on how\u00a0lsof<\/code>\u00a0works, along with some common use cases. For further reading, see the manpage of\u00a0lsof<\/code>\u00a0on your system.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","format":"standard","manualknowledgebasecat":[242],"manual_kb_tag":[440],"_links":{"self":[{"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manual_kb\/2877"}],"collection":[{"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manual_kb"}],"about":[{"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/types\/manual_kb"}],"author":[{"embeddable":true,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/comments?post=2877"}],"version-history":[{"count":1,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manual_kb\/2877\/revisions"}],"predecessor-version":[{"id":2878,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manual_kb\/2877\/revisions\/2878"}],"wp:attachment":[{"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/media?parent=2877"}],"wp:term":[{"taxonomy":"manualknowledgebasecat","embeddable":true,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manualknowledgebasecat?post=2877"},{"taxonomy":"manual_kb_tag","embeddable":true,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manual_kb_tag?post=2877"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}