【发布时间】:2011-02-01 09:23:15
【问题描述】:
我正在尝试测试单个文件是否使用 lsof 打开。还有比这更快的方法吗?
$result = exec('lsof | grep filename | wc -l');
if($result > 0) {
//file is open
}
如果您知道文件名,我认为它们必须是一种仅测试一个文件的方法。我真正需要的只是一个真假。
【问题讨论】:
我正在尝试测试单个文件是否使用 lsof 打开。还有比这更快的方法吗?
$result = exec('lsof | grep filename | wc -l');
if($result > 0) {
//file is open
}
如果您知道文件名,我认为它们必须是一种仅测试一个文件的方法。我真正需要的只是一个真假。
【问题讨论】:
好吧,你可以跳过wc,使用grep的返回值(如果grep检测到模式返回0(即成功),如果没有检测到模式返回1(即不成功)):
if lsof | grep filename > /dev/null; then
# filename is in output of lsof
fi
您可以通过使用 grep 的 -l 标志来稍微改进一下:
if lsof | grep -l filename > /dev/null; then
...
这告诉 grep 一旦检测到第一个匹配项就停止查找。
【讨论】:
-m 1 选项,这样您实际上会得到匹配的行而不是找到匹配项的文件名 (stdin)。 (否则,很好地替代使用-l。)
我找到了一个更好的方法。使用lsof(4.63版本测试),可以直接查询特定文件:
if lsof filename > /dev/null; then
# file is open
fi
【讨论】:
使用fuser。如果指定的任何文件正在使用,则返回非零值,如果它们全部可用,则返回零。
【讨论】:
不要。当您尝试对结果做任何事情时,答案可能会改变。相反,请尝试对文件执行您打算执行的任何操作并处理“正在使用”错误或“共享冲突”。
【讨论】:
flock 或其他一些锁定机制,否则您不会得到任何“正在使用”或“共享违规”错误 - 您只会愉快地混淆您的文件。
lsof 没有实现任何目标。对于调试日志收集,您确实需要转向文件系统跟踪。为了避免由于同时访问而造成的损坏,您需要确定格式是要更新还是重写。将在适当位置更新的数据库需要各方锁定,您只需丢弃任何无需访问它的软件,因为记录锁定是如此基本。其他适合覆盖的格式,应该先写一个临时文件,然后重命名,完全避免乱码。