經過inotify擴展監控文件或目錄的變化,若是發生變化,就執行命令。php
能夠應用於 swoole 中,若是文件發生變化,就執行 kill -USR1 進程PID 來實現熱更新。shell
<?php class Monitor { public $dir = ''; public $cmd = ''; public $timeout = 1; public function __construct() { if (!extension_loaded('inotify')) { echo '請安裝inotify擴展', PHP_EOL; exit; } //解析命令行參數,有一個:號表示必填項 $opts = getopt('', ['dir:', 'cmd:']); if (!$opts) { echo '參數輸入錯誤', PHP_EOL; exit; } if (empty($opts['dir'])) { echo '--dir 是必填項', PHP_EOL; exit; } if (empty($opts['cmd'])) { echo '--cmd 是必填項', PHP_EOL; exit; } $this->dir = $opts['dir']; $this->cmd = trim($opts['cmd']); $this->run(); } //對目錄進行監控 public function run() { $dirs = $this->getDirs($this->dir); if (empty($dirs)) { return false; } $fd = inotify_init(); //設置爲非阻塞模式 stream_set_blocking($fd, 0); foreach ($dirs as $dir) { $watch = inotify_add_watch($fd, $dir, IN_MODIFY | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_CLOSE_WRITE); if (!$watch) { echo "{$dir} 添加監控錯誤", PHP_EOL; exit; } } while (true) { $reads = [$fd]; $write = []; $except = []; if (stream_select($reads, $write, $except, $this->timeout) > 0) { if (!empty($reads)) { foreach ($reads as $read) { //文件改變 $fileChg = false; //目錄改變 $dirChg = false; //從可讀流中讀取數據 $events = inotify_read($read); $fileName = ''; foreach ($events as $event) { $fileName = $event['name']; switch ($event['mask']) { case IN_CREATE: case IN_DELETE: $fileChg = true; break; case 1073742080: case 1073742336: $dirChg = true; break; } } if ($fileChg) { echo "文件 {$fileName} 發生改變, 執行命令 {$this->cmd}", PHP_EOL; echo shell_exec($this->cmd), PHP_EOL; } if ($dirChg) { echo "目錄 {$fileName} 發生改變, 執行命令 {$this->cmd}", PHP_EOL; echo shell_exec($this->cmd), PHP_EOL; return $this->run(); } } } } } return true; } //遞歸的獲取當前目錄下全部子目錄路徑 public function getDirs($dir) { $dir = realpath($dir); $dh = opendir($dir); if (!$dh) { return []; } $dirs = []; $dirs[] = $dir; while (($file = readdir($dh)) !== false) { if ($file == '.' || $file == '..') { continue; } $full = $dir . DIRECTORY_SEPARATOR . $file; if (is_dir($full)) { $dirs = array_merge($dirs, $this->getDirs($full)); } } closedir($dh); return $dirs; } } (new Monitor());
演示以下所示:swoole