367  words
  2  minutes 
  Using lsof on macOS 
 Using lsof on macOS
lsof stands for “list open files”. Here are some very basic usage notes for the version that ships with macOS.
Listing processes that have a specific file open
~ % lsof /tmp/covid-smaller.dbCOMMAND   PID  USER   FD   TYPE DEVICE  SIZE/OFF      NODE NAMEPython  17990 simon    6r   REG    1,5 747413504 187550734 /private/tmp/covid-smaller.dbPython  17990 simon   12r   REG    1,5 747413504 187550734 /private/tmp/covid-smaller.dbNote that this file is opened twice by the same process (Datasette maintains multiple connections to the same SQLite database). The PID column is useful.
In the FD column 6r means “file descriptor 6, open for read access”. w would mean write access, u would mean both.
Files for a specific process
I removed some of the output here trying to leave the most interesting bits:
~ % lsof -p 17990COMMAND   PID  USER   FD     TYPE             DEVICE  SIZE/OFF                NODE NAMEPython  17990 simon  cwd      DIR                1,5      1344           174186151 /private/tmpPython  17990 simon  txt      REG                1,5     49400           163507251 /usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/Resources/Python.app/Contents/MacOS/PythonPython  17990 simon  txt      REG                1,5   3632512           163507083 /usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/Python...Python  17990 simon  txt      REG                1,5     50840           152019254 /usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/markupsafe/_speedups.cpython-39-darwin.so...Python  17990 simon  txt      REG                1,5   1069536           148927587 /usr/local/Cellar/sqlite/3.36.0/lib/libsqlite3.0.dylibPython  17990 simon  txt      REG                1,5     24552           179047672 /usr/local/Cellar/datasette/0.58.1/libexec/lib/python3.9/site-packages/bpylist/bplist.cpython-39-darwin.soPython  17990 simon  txt      REG                1,5   1572480 1152921500312757159 /usr/lib/dyldPython  17990 simon    0u     CHR               16,5   0t94656                6931 /dev/ttys005Python  17990 simon    1u     CHR               16,5   0t94656                6931 /dev/ttys005Python  17990 simon    2u     CHR               16,5   0t94656                6931 /dev/ttys005Python  17990 simon    3u  KQUEUE                                                  count=0, state=0xaPython  17990 simon    4u    unix 0x67a396d5b54b61cb       0t0                     ->0x67a396d5b54b522bPython  17990 simon    5u    unix 0x67a396d5b54b522b       0t0                     ->0x67a396d5b54b61cbPython  17990 simon    6r     REG                1,5 747413504           187550734 /private/tmp/covid-smaller.dbPython  17990 simon    7u  KQUEUE                                                  count=0, state=0xaPython  17990 simon    8u    unix 0x67a396d5b54b68d3       0t0                     ->0x67a396d5b54b5613Python  17990 simon    9u    unix 0x67a396d5b54b5613       0t0                     ->0x67a396d5b54b68d3Python  17990 simon   10u    IPv4 0x67a396d59c718b2b       0t0                 TCP localhost:8422 (LISTEN)Python  17990 simon   12r     REG                1,5 747413504           187550734 /private/tmp/covid-smaller.dbThe column with FD=cwd, TYPE=DIR shows the working directory for the process.
The TYPE=IPv4 one is interesting, it shows that we are listening on localhost:8422.
PID listening on a port
To find out which process is listening on a specific port, use lsof -i :8000. For example:
~ % lsof -i :8000COMMAND   PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAMEPython  23862 simon    3u  IPv4 0x78af109648024857      0t0  TCP localhost:irdmi (LISTEN) Using lsof on macOS 
  https://mranv.pages.dev/posts/using-lsof-on-macos/