首页 > 解决方案 > Python 3:subprocess.run('mv') 使目标保持打开状态

问题描述

我有一个脚本,它使用一个非常简单的基于文件的 IPC 与另一个程序进行通信。我用新内容编写了一个 tmp 文件,并将mv其写入 IPC 文件以保留内容(其他程序侦听重命名事件)。

但现在问题来了:这工作了 2 或 3 次,但随后交易卡住了。

time.sleep(10)
# check lsof => target file not opened
subprocess.run(
    "mv /tmp/tempfile /tmp/target",
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    universal_newlines=True,
    shell=True,
)
# check lsof => target file STILL open
time.sleep(10)

/tmp/tempfile将为每次写作做好准备

第一次运行的结果是:

$ lsof /tmp/target
COMMAND  PID        USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
python  1714      <user>   3u   REG   0,18      302 10058 /tmp/target

让它保持打开状态,直到我终止主 python 程序。连续运行按预期更改内容、inode 和文件描述符,但它仍然打开我不希望从mv.

当具有上述这些行的 python 程序关闭时,文件最终被关闭。

编辑:

发现错误:错误处理tempfile.mkstemp(). 请参阅:https ://docs.python.org/3/library/tempfile.html#tempfile.mkstemp

我像这样创建了临时文件:

_fd, temp_file_path = tempfile.mkstemp()

我丢弃了_fd默认打开的文件描述符。我没有关闭它,所以即使在移动之后它也保持打开状态。这导致了一个打开的目标,因为我只是lsof在目标上,我没有看到临时文件已经打开。这将是更正的版本:

fd, temp_file_path = tempfile.mkstemp()
fd.write(content)
fd.close()

# ... mv/rename via shell execution/shutil/pathlib

非常感谢大家的帮助和建议!

标签: pythonpython-3.x

解决方案


你有什么理由不使用shutil.move吗?否则可能需要等待mv命令完成移动然后杀死它,读取标准输入,运行类似的东西

p = subprocess.run(...)
# wait to finish moving/read from stdin
p.terminate()

当然terminate会有点苛刻。

编辑:根据您的使用rsync,它不是 python 的一部分,可能是一个优雅的解决方案,可以让您的数据在网络上同步,而无需编写任何代码


推荐阅读