Bash:查找排除目录错误

时间:2018-07-06 14:25:39

标签: bash shell git-bash

我有这个文件夹结构:

leave_type

服务器正在监视incoming/ Printing/ |------ done/ \------ error/ 文件夹,等待Printing文件出现在其中。检测到新文件后,它将发送到打印机,并在成功时将其移动到.txt或在失败时将其移动到done

我正在处理的脚本必须执行以下操作:扫描error目录中的文件,并将它们一个接一个地传输到incoming文件夹中。我从在StackOverflow上找到的这个脚本开始:

Printing

问题在于它检测到两个子文件夹#!/usr/bin/env bash while true; do target="/var/www/test"; dest="/var/www/incoming"; find $dest -maxdepth 1 -type f | sort -r | while IFS= read -r file; do counter=0; while [ $counter -eq 0 ]; do if find "$target" -maxdepth 0 -mindepth 0 -empty | read; then mv -v "$file" "$target" && counter=1; else echo "Directory not empty: $(find "$target" -mindepth 1)" sleep 2; fi; done; done done done并拒绝复制文件,始终发出“目录不为空”消息。 我需要一种使脚本忽略那些文件夹的方法。

我尝试了error命令中涉及find-prune的变体,但是没有发现任何有效的方法。如何根据自己的需要在内部循环中修复! -path命令?

1 个答案:

答案 0 :(得分:0)

有问题的命令是这样的:

find "$target" -maxdepth 0 -mindepth 0 -empty

首先要认识到它的作用:

  • 它在由"$target"命名的目录(如果有)上运行
  • 由于-maxdepth 0,它仅测试 该路径本身
  • -empty谓词匹配 empty 常规文件和目录
  • -mindepth 0是默认设置;明确表示它没有其他作用)

由于您期望目标目录从不为空(它将至少包含您描述的两个子目录),因此您需要一种不基于-empty的方法谓语。 find无法调节“空”的含义。

有多种方法可以解决此问题,有些包括find,而有些则没有。由于find有点重量级,并且对于复杂的测试来说它的参量语法有些晦涩,因此我建议使用以下替代方法:ls + grep。示例:

# File names to ignore in the target directory
ignore="\
.
..
done
error"

# ...

while /bin/true; do
  files=$(ls -a "$target" | grep -Fxv "$ignore")

  if [ -z "$files" ]; then
    mv -v "$file" "$target"
    break
  else
    # non-ignored file(s) found
    echo "Directory not empty:"
    echo "$files"
    sleep 2
  fi
done

注意事项:

  • -a选项被提供给ls来捕获点文件,从而匹配find的{​​{1}}谓词的行为。相反,您可能更愿意忽略点文件,在这种情况下,您可以简单地删除-empty

  • -a的{​​{1}}选项指定它要匹配固定字符串(不是模式),而F选项告诉它必须匹配整行。 grep选项颠倒了匹配的含义,因此这三者共同导致匹配行(文件名),而不是-x变量中指定的行。

  • 将文件列表捕获到一个变量中比重新计算它更有效,并且避免了在文件移动之前就检测到文件的竞争情况。通过捕获文件列表,您可以确保重新概括脚本决定延迟的基础数据。

  • 文件名可能包含换行符,精心设计的包含换行符的文件名可能会使该脚本误认为目录(实际上)为空,而实际上却不是。如果您对此感到担忧,那么您将需要更强大的功能,也许毕竟使用-v