tags:

views:

394

answers:

2

I did the following:

nohup find / &

rm nohup.out

Oddly, the nohup -command continued to run. I awaited for a new file to be created. For my surprise there was no such file. Where did the stdout of the command go?

+2  A: 

Removing a file in UNIX does two things:

  • it removes the directory entry for it.
  • if no processes have it open and no other directory entries point to it (hard links), it releases the space.

Your nohupped process will gladly continue to write to the file that used to be called nohup.out, but is now known as nothing but a file descriptor within that process.

You can even have another process create a nohup.out, it won't interfere with the first.

When all hard links are gone, and all processes have closed it, the disk space will be recovered.

paxdiablo
If it is possible to change the location of inode to /dev/null, I assume it is possible to change it to other locations. Suppose I want the stdout from the find -command to different location every 5 seconds. I know that I could create a new hard link in each step, removing always the last link. However, I cannot understand the process. How can you ensure that every 5 seconds' stdouts have a distinct inode number? How can you ensure an asynchronous process so you surely record everything?
Masi
That first sentence is confusing, @SQ, I don't think you understand what an inode is - it's really just an ID for an underlying file (the data, not the directory entry). By changing to /dev/null, do you mean "find / >/dev/null"? find simply outputs to the file descriptor it inherits from the shell. Using redirection, the shell attaches stdout to a file (or device driver such as /dev/null) then fork/execs find which will use that stdout descriptor. find itself has no knowledge of what file it is writing to, just a descriptor. So it won't recreate a directory entry since its file still exists.
paxdiablo
@SimpleQuestions: very few programs open a file each time they write, especially not when they are writing to standard output. They simply continue to use an open file descriptor. Once your program starts writing to a given file, it continues to do so. You can't change which file it writes to by (re)moving the file.
Jonathan Leffler
Hey, that's what I said, only yours in in understandable English :-)
paxdiablo
In future if you want to truncate a log file while a process is writing to it use the following command:cat /dev/null > nohup.out
teambob
+2  A: 

That's standard behaviour on Unix.

When you removed the file, the last link in the file system was removed, but the file was still open and therefore the output of find (in this case) was written to disk blocks in the kernel buffer pool, and possibly even to disk. But the file had no name. When find exited, no process or file (inode) referenced the file, so the space was released. This is one way that temporary files that will vanish when a program exits are created - by opening the file and then removing it. (This presumes you do not need a name for the file; clearly, if you need a name for the temporary, this technique won't work.)

Jonathan Leffler
+1 good practical example about temp files
Masi
As the rm-command removes the last link, the data is still on the disk, unless it is not overwriten. What is the probability to find the data without knowing its last link?
Masi
Probability nil - unless you go poking at the raw device. The file uses up space (df will report it as 'in use'). However, there is no name by which you can access it. The original process could, in theory, read the data (as well as write it); of course, `find` won't do that.
Jonathan Leffler