b2-osx108v8-01:~ bamboo$ lsof -p 264
<lines removed>
java    264 bamboo   20w     REG               1,2    240906 14883372 /Users/bamboo/bamboo-agent-home/xml-data/build-dir/ST-SSINR-B2OSML/SimbaProcessManager.log.0
<lines removed>

The /Users/bamboo/bamboo-agent-home/xml-data/build-dir/ST-SSINR-B2OSML directory has already been deleted, but the file is still open by our daemon process. How can I look at this log? On Linux, I'd use /proc/264/fd/20, but that doesn't seem to be available on OSX.

2 Answers 2



If this was Linux, you could also use a gdb trick. But it turns out we can rule out that trick on OS X, because it relies on Linux-specific behaviour of /dev/fd/ (/proc/self/fd/).

That's all I know, I don't have a positive suggestion.


It could go horribly horribly wrong, but have you considered gdb? Two miracles in one package: a C interpreter, and a way to inject code into the process of your choice! Apparently you can also use it for debugging.

Fortunately the C standard library also includes a function which interprets scripts. The scripting language on your platform might be more convenient to write than C...

I thought of a script which uses less for OS X. This is a fragile hack to seek back to the start of the logfile based on OS X, bash: less works on open file descriptors, cat doesn't After reading the whole log file with less, the FD position should be at the end of the file, which is hopefully the original position before we meddled with it.

<EDIT>But it only works if the file was also opened for reading. According to your lsof output, the file was only open for writing.</EDIT>

gdb -p 264 <<EOF
call (int) system("exec </dev/null >/tmp/log 2>&1; less /dev/fd/20")

I cast the return type, because otherwise my system complained that it did not know the return type of system(). Presumably this also means that it wasn't sure of the argument types either, so this is already sounding like such a great idea.

Using system() to manipulate file descriptors somehow worked when I tried it on my Linux box... once. I don't promise it will always work :). E.g., technically this is not guaranteed to be safe if the program is executing a signal handler, or indeed system() itself. (system() is not one of the few functions which is guaranteed to be "re-entrant").

  • 1
    This seems to have worked, although the created file is empty (not sure if any output was still buffered in the process, it was empty for other reasons, or the cat somehow failed, which seems unlikely)
    – Bwmat
    Jun 5, 2018 at 20:48
  • 1
    @Bwmat ah. hmm. I didn't test this quite properly. I think it will fail because the file is only open for writing (and probably won't seek back to the start of the file anyway?). So I suspect this can't be made to work.
    – sourcejedi
    Jun 5, 2018 at 20:54
  • @Bwmat I have revised my command to include some error handling :). Still not tested.
    – sourcejedi
    Jun 5, 2018 at 20:55
  • 2
    opening /dev/fd/n on Linux opens the file pointed by the fd anew. You get a new and unrelated open file description. It's not doing the same as a dup() like on other systems. Jun 5, 2018 at 21:16
  • 1
    @Bwmat, you can seek in zsh and ksh93, not plain sh. You can always call perl to do the seek, but in any case, that won't help if the file has been open in write-only mode. Jun 5, 2018 at 21:37

I have not verified that icat behaves correctly when operating on a block device, nor that Mac OS has block devices, nor whether doing the below will EAT YOUR DATA.

It might be possible to use icat /dev/MY-DEVICE 14883372. The icat command is provided by The Sleuth Kit® (TSK).


(You already mentioned Linux. This idea was inspired by debugfs, which has a command to do the same thing for the Linux filesystems ext2/ext3/ext4).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .