2013-12-19 3 views
1

У меня есть файл в каталоге, который я хотел бы заменить текущей версией каждый час. Я использую shell_exec() для zcat файл и процесс его разархивирования и записи занимает около 4 минут. Перед этим чтением и письмом я записываю имя файла, который уже находится в каталоге, чтобы я мог unlink после записи нового файла. Но это не происходит в том порядке, в котором я бы хотел. PHP выполняет удаление при обработке shell_exec. Только после четырех минут пустой директории я вижу новый написанный файл. Есть ли способ отложить это удаление или сделать его обратным вызовом для процессов чтения и записи?Как я могу отложить удаление файла до тех пор, пока не будет написан новый файл?

$log_files = scandir("/cached_logs/"); 

foreach ($log_files as $key => $val){ 
    //non-secure file to delete 
    if (preg_match("/^access/", $val)){ 
     $log_to_delete= $val; 
    } 
} 

$ssl_command_string = "zcat log." . $datetime . ".gz"; 

//execute 
$ssl_res = shell_exec($ssl_command_string); 

//build the local directory and append the new file name with the current $datetime 
$cached_ssl_file_name = "/cached_logs/log." . $datetime . ".txt"; 

//open the file handle 
$new_ssl = fopen($cached_ssl_file_name, 'w') or die("can't open file"); 

//write 
fwrite($new_ssl, $ssl_res); 

//close 
fclose($new_ssl); 

unlink("/cached_logs/" . $log_to_delete); //this is defined properly above, I just didn't post it as it's irrelevant to the problem. 

Edit: разъяснила некоторые вещи и исправлены ошибки синтаксиса в результате очистки информации

+0

Где находится '$ datetime'? Я подозреваю, что возможно выполнение произвольных команд с помощью этого кода. – Julio

+0

@Louis Я установил datetime, используя 'date()', поэтому нет, на самом деле это не проблема. – 1252748

+0

Странно, я уверен, что 'shell_exec' является блокирующей командой. Может быть, попробуйте 'proc_open' для большего контроля над внешним процессом? – quickshiftin

ответ

1

звучит для меня как-то странно, что происходит. Основная причина заключается в том, что блоки AFAIK, shell_exec, что означает, что он будет ждать, пока команда, которую он дал, завершилась до того, как будет запущен следующий оператор PHP.

Я собрал минимальную версию сценария образца, и он отлично работает для меня.

<?php 
$log_file = './my-access.log.gz'; 

$ssl_command_string = "zcat $log_file"; 

//execute 
$ssl_res = shell_exec($ssl_command_string); 

$cached_ssl_file_name = "./my-access.log.txt"; 

//open the file handle 
$new_ssl = fopen($cached_ssl_file_name, 'w') or die("can't open file"); 

//write 
fwrite($new_ssl, $ssl_res); 

//close 
fclose($new_ssl); 

unlink($log_file); 
0
if(is_resource($new_ssl)){ 
//Handle still open 
fclose($new_ssl); 
@unlink("cached_logs/" . $log_to_delete); 
} 
+0

используйте @unlink() вместо unlink(), чтобы устранить ошибку, если она есть – Rahi

+0

Не будет ли это просто не удалять старый журнал?Он не будет пытаться до тех пор, пока $ new_sll не станет ресурсом? – 1252748

+0

Нет, он удалит старый журнал, как только ресурс будет доступен. – Rahi

Смежные вопросы

 Смежные вопросы