如何复制文件夹中的所有文件,但不包括正在写入的文件?

Goo*_*bot 12 bash find shell-script file-copy files

downloading通过HTTPie将多个文件下载到一个文件夹。bash 脚本旨在处理下载的文件,我尝试将下载的文件复制到另一个文件夹中

find /folder/downloading -type f -exec mv '{}' /folder/downloaded \;
Run Code Online (Sandbox Code Playgroud)

但这也会复制尚未完成的文件。我试图通过添加-mmin +5到命令来限制对旧文件的传输。离开正在写入的文件并仅传输下载的文件的有效命令是什么?

Sté*_*las 11

效率不高,但你可以这样做:

find /folder/downloading -type f -exec sh -c '
  for file do
    lsof -F a "$file" | grep -q w || mv "$file" /folder/downloaded
  done' sh {} +
Run Code Online (Sandbox Code Playgroud)

即检查该文件不与列出w仪式a在CCESS模式ls的吨of尔斯之前mÒv荷兰国际集团。

通常在基于 Linux 的操作系统上发现的psmisc实现fuser具有一个-w功能(检查打开的文件以进行写入),但不幸的是它只能-k用于杀死相应的进程。但是,您似乎仍然可以通过使用什么都不做的伪信号 0 来使用它:

find /folder/downloading -type f -exec sh -c '
  for file do
    fuser -s -w -k -0 "$file"  || mv "$file" /folder/downloaded
  done' sh {} +
Run Code Online (Sandbox Code Playgroud)

如果您想查看阻止移动的进程,请删除-s(甚至用 替换-v)。

请注意,如果您不是以超级用户身份运行这些命令,您将只能获得有关您的进程的信息。如果下载文件的进程以不同的用户身份运行,它们将不会被检测到。

另请注意,除非您将文件移动到不同的文件系统,否则移动文件不会阻止当前正在写入文件的任何进程完成写入。

不过,根据他们已经设计之后做的,他们可能会被倘若他们写完,文件就不再有混淆(例如,如果他们想要下载后更改文件的某些属性,这样做通过文件描述符(如chmod()vs fchmod(),或者utimes()不能通过文件描述符完成))。

  • @Joe,这就是内联脚本的“$0”。也就是说,它为该内联脚本提供了一个 _name_。例如,该名称可能会用于诸如 `<name>: fuser: command not found` 之类的错误消息中,因此在这种情况下,`sh` 通常是一个不错的选择,可以明确报告该错误消息的内容(这也是它的内容)如果我们在内联脚本之后根本没有给出任何参数,那就是)。 (2认同)