Pet*_*vac 10 linux monitoring shell-script lsof open-files
我想在外部进程关闭后立即移动它创建的大文件。
这个测试命令正确吗?
if lsof "/file/name"
then
# file is open, don't touch it!
else
if [ 1 -eq $? ]
then
# file is closed
mv /file/name /other/file/name
else
# lsof failed for some other reason
fi
fi
Run Code Online (Sandbox Code Playgroud)
编辑:该文件代表一个数据集,我必须等到它完成才能移动它,以便另一个程序可以对其进行操作。这就是为什么我需要知道外部进程是否完成了文件。
Gra*_*eme 11
从lsof手册页
如果检测到任何错误,Lsof 将返回一 (1),包括无法定位命令名、文件名、Internet 地址或文件、登录名、NFS 文件、PID、PGID 或要求列出的 UID。如果指定了 -V 选项,lsof 将指示它未能列出的搜索项。
所以这表明你的lsof failed for some other reason条款永远不会被执行。
您是否尝试过在外部进程仍然打开时移动文件?如果目标目录在同一个文件系统上,那么这样做应该没有问题,除非您需要从第三个进程的原始路径下访问它,因为底层 inode 将保持不变。否则我认为mv无论如何都会失败。
如果你真的需要等到你的外部进程处理完文件,你最好使用阻塞命令而不是重复轮询。在 Linux 上,您可以使用inotifywait它。例如:
inotifywait -e close_write /path/to/file
Run Code Online (Sandbox Code Playgroud)
如果您必须使用lsof(也许是为了便携性),您可以尝试以下操作:
until err_str=$(lsof /path/to/file 2>&1 >/dev/null); do
if [ -n "$err_str" ]; then
# lsof printed an error string, file may or may not be open
echo "lsof: $err_str" >&2
# tricky to decide what to do here, you may want to retry a number of times,
# but for this example just break
break
fi
# lsof returned 1 but didn't print an error string, assume the file is open
sleep 1
done
if [ -z "$err_str" ]; then
# file has been closed, move it
mv /path/to/file /destination/path
fi
Run Code Online (Sandbox Code Playgroud)
正如下面@JohnWHSmith所指出的,最安全的设计将始终使用上述lsof循环,因为可能会有多个进程打开文件进行写入(示例情况可能是编写不良的索引守护进程,它使用读取打开文件) /write 标志,当它真的应该是只读的)。inotifywait仍然可以代替 sleep 使用,只需将 sleep 行替换为inotifywait -e close /path/to/file.
| 归档时间: |
|
| 查看次数: |
15630 次 |
| 最近记录: |