您所描述的是File Alteration Monitor的工作。
首先,鉴于您是从 shell 启动的,您现有的“incrontab”解决方案是一个很好的起点。incrontab 是基于inotify(7)的解决方案这一事实是一个巨大的优势。这意味着您没有轮询,这可以节省 CPU。
您要求的是 shell 和系统级解决方案,而我不是 Flash 程序员,所以我会坚持您的问题,尽管我认为更好的解决方案是创建一个可能使用 AS3 的 Flash“包装器”加载器类来吸收你现有的 SWF 并从 incrontab 启动的东西接收通知。Flash 编程超出了这个答案的范围,尽管它可能会提供一个更优雅的解决方案。
所以...
您当前的方法包含一个启动脚本,该脚本首先终止任何现有gtk-gnash
进程,然后运行一个新进程。当 incrontab 看到文件发生更改时,它会从头开始重新启动。如果您相信您的闪存应用程序永远不会崩溃和退出,并且您总是有完美的时机,那么这是一个可行的解决方案。它的一个问题是你在一个进程的死亡和下一个进程的开始之间有一个未知的延迟。您killall
发送的信号gtk-gnash
可能会立即响应,也可能会在暂停后响应。稍作停顿,您可能会发现自己在旧的 SWF 完全消失之前启动了 SWF。暂停时间较长,您可能会短暂显示您的桌面。
更好的解决方案可能是简单地在循环中启动 SWF:
#!/bin/sh
while true; do
date '+[%Y-%m-%d %T] myfile.swf relaunched' >> /var/log/swf.log
gtk-gnash /home/my_username/path/myfile.swf
done
然后让 incrontab 仅仅杀死现有的进程:
/home/my_username/path/myfile.swf IN_MODIFY killall gtk-gnash
通过将 killall 与启动分开,您可以确保 gtk-gnash 的新实例在旧实例实际退出并将控制权返回给包装它的 shell 脚本之前不会启动。
当然,您也可以不使用 incrontab,而是安装inotify-tools
软件包并让循环运行:
#!/bin/sh
while inotifywait -e modify /home/my_username/path/myfile.swf; do
killall gtk-gnash
done
相同的系统调用,相同的效果,不同的前端。
如果你想非常小心你正在杀死的进程,你也可以将 gtk-gnash 的 pid 存储在一个临时文件中。这是对 Flash 播放器包装器的另一种看法:
#!/bin/sh
while true; do
date '+[%Y-%m-%d %T] myfile.swf relaunched' >> /var/log/swf.log
gtk-gnash /home/my_username/path/myfile.swf &
echo $! > /var/run/gtk-gnash.pid
wait
done
而 incrontab 行:
/home/my_username/path/myfile.swf IN_MODIFY xargs kill < /var/run/gtk-gnash.pid
您可能会采用的另一种减少终止/重新启动的可见效果的策略是,在 myfile.swf 以最少内容或没有内容运行时对其进行截图,然后将其用作播放器的桌面壁纸。(或等效的。我不知道你是如何设置的。)我为几年前设置的数字标牌解决方案做了类似的事情——有时我们需要杀死并重新启动一个独立的播放器,所以我们只制作了显示的第一页的“框架”。当我们终止 flashplayer 进程时,系统“似乎”在其框中没有内容的情况下重置……然后,一秒钟后,内容会出现。(是的,这是一个黑客。)
另一个提示:我一直发现 Adobe 的独立 Flash 播放器(“投影仪”)比 gtk-gnash 更可靠、更兼容。您可以在Adobe 支持中心下载页面找到 Adobe 的独立播放器,该页面不同于其标准的 Flash Player 下载页面。