Python Linux:如何*立即*将文件移动到 USB 以避免 OS 不同步和 USB 突然被拔出的问题

Python on Linux: How to *immediately* move files to USB to avoid issues from OS not syncing and the USB suddenly being pulled

我有一个 Python 脚本,它使用 shutil 自动将文件从内部文件夹移动到任何现有的 USB 驱动器。即使在脚本关闭后,OS 似乎并不总是真正将文件移动到 USB 驱动器,直到稍后。我的研究表明 OS 出于磨损均衡的目的进行这种延迟,但我不确定这是否是真正的解释。有没有我可以添加的东西(最好添加到我的 Python 脚本或绑定到它)以便写入实际上会立即执行?也许是一种不同的文件移动方式,某种要求立即同步的方式,验证文件是否真的被移动,或者做一些需要 OS 才能真正执行移动的后续操作?

明确地说,我不是在谈论在写入活动发生时拔出 USB 的问题。这些文件总共没有多少 KB,即使在 40 多秒后拔出驱动器,我也看到了问题。驱动器没有闪烁。我没有看到一些文件被移动而其他文件没有移动的部分写入,这表明我在中途中断了它。即使这是问题所在,我认为我的问题仍然是一个有效的问题。

背景:我在 Pi4 上 运行ning Raspbian Buster 桌面版和 Python 3.7.3。我想 运行 这个 Pi 没有键盘或显示器,这样就不需要用户干预来拉动驱动器或更换驱动器。尽管没有显示器,但我必须 运行 桌面,否则 Pi 不会自动挂载 USB 驱动器,但这是一个单独的问题。我是菜鸟,所以特别详尽的解释将特别感激。

正如@tdelaney 在他们的评论中所说,彻底到过分杀伤力的方法是在文件对象上调用 flush(),然后在其文件描述符上调用 os.fsync(),因为 Raspbian 是基于 Linux 内核的,所以在刷新缓冲区之前不应该 return。

但是,如果您正在使用 shutil.copy* 函数之一,则没有文件对象来调用这些函数,因此您可以调用 os.system("sync").

但请注意,即使内核正在拍手并说“是的,刷新了那些缓冲区”,数据仍可能通过设备驱动程序内部工作,并且尚未实际写入媒体。除非您手动驱动 USB 逻辑,否则您不能 100% 保证它一直通过,但下一个最好的办法是添加一个命令来卸载文件系统。

问题是来自 U 盘的代码 运行 无法卸载包含自身的文件系统,所以如果你的 Python 在 U 盘上,它就无法卸载。不过,您可以从命令行手动执行此操作。只需 umount /path/to/usb/stick 即可。