Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete file if currently not being accessed

I am looking for a solution I need to delete log files, but there might be a possibility that they are being accessed at the moment the delete call is made. By being accessed, I mean a process is either reading or writing to the file. In such cases, I need to skip the file instead of deleting it. Also my server is Linux and PHP is running on Apache.

What I am looking for is something similar to (in pseudo-code):

<?php
$path = "path_to_log_file";
$log_file = "app.log"; 
if(!being_accessed($log_file))
{
  unlink($path.$log_file);
}
?>

Now my question is how can I define being_accessed? I know there might not be a language function do to this directly in PHP. I am thinking about using a combination of sections like last_access_time (maybe?) and flock (but this is useful only in those conditions where the file was flock-ed by the accessing application)

Any suggestions/insights welcome...

like image 647
Undefined Variable Avatar asked Aug 29 '12 19:08

Undefined Variable


2 Answers

In general you will not be able to find that out without having administration rights (and i.e. be able to run tools like lsof to see if file of your is listed. But if your scripts are running on linux/unix server (which is the case for most hosters) then you do not need to bother, because filesystem will take care of this. So for example, you got 1GB file and someone is downloading this file. It is safe for you to delete the file (with unlink() or any other way) event if that downloader just started and it will not interfere his downloading, because filesystem knows that file is already open (some processes holds a handle) so it will only mark it, let say invisible for others (so once you try to list folder content you will no longer see that file, but if your file is big enough you could try to check available disk space (i.e. with df, to see it would still be occupied)) but those how kept the handle will still be able to use it. Once all processes close their handle file will be physically removed from media and disk space freed. So just unlink when needed. If you bother about warning unlink may throw (which may be a case on Windows), then just prepend your call with @ mark (@unlink()) to disable any warning this call may throw in runtime

like image 90
Marcin Orlowski Avatar answered Oct 03 '22 09:10

Marcin Orlowski


You'd simply change your code this way (if you are doing it repetitively):

<?php
$path = "path_to_log_file";
$log_file = "app.log"; 
@unlink($path.$log_file);

Notice the @ to avoid getting an error in case the file is not deletable, and the lack of ending tag (ending tags are source of common errors and should be avoided)

like image 23
Parallelis Avatar answered Oct 03 '22 10:10

Parallelis