DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

find 把 -exec 末尾改成 + 后报 missing argument:{} 必须紧挨结束符

GNU find 的批量 -exec 要求唯一的 {} 紧挨 +。用 GNU mv -t 调整目标目录位置,或保留逐文件形式,先明确搜索范围与冲突处理。

下面的逐文件移动命令可以运行,但把结尾的 \; 直接换成 + 后,GNU find 报 missing argument to '-exec':

find /srv/uploads/user -type f -mtime +30 -exec mv '{}' /srv/archive/user/ +

路径是示例。问题在于批量形式要求唯一的 {} 放在命令尾部,紧挨 +。当前 {} 后还有目标目录,find 无法把它解释成合法的批量 -exec,不是文件权限或目标目录不存在。

分号形式每个文件调用一次,+ 形式按批传入

-exec command '{}' \; 每找到一个匹配项,就调用一次命令。分号需要转义或加引号,避免被 shell 当成自己的命令分隔符。

-exec command '{}' + 将多个匹配路径追加到命令参数末尾,按命令长度限制分批调用。它可能调用多次,不能承诺所有匹配文件只启动一次进程。

普通 mv source... destination 把目标目录放在最后,与 {} + 的尾部要求冲突。GNU mv 提供 -t,可以把目标目录移到选项位置。

先查看候选,再在受控目录中移动

先保留需要归档的文件,并确认目标目录已存在、可写、位于输入目录之外。下面的只读检查限定到用户目录的第一层普通文件,按原来的 -mtime +30 条件列出候选;请按需求替换目录和时间条件:

find /srv/uploads/user -maxdepth 1 -type f -mtime +30 -print

-mtime 按完整的 24 小时区间计算,不是按日历月份。不要只看到数字 30 就假定它精确表示某个日历日期之前的全部文件。

确认名单后,可在有人处理提示的交互终端使用 GNU 工具的批量形式:

find /srv/uploads/user -maxdepth 1 -type f -mtime +30 \
  -exec mv -i -t /srv/archive/user -- '{}' +

-t 指定目标目录,{} 因而可以紧挨 +。-i 在目标同名文件将被覆盖时询问,不适合作为无人值守任务的默认策略。自动归档应提前明确冲突处理、错误记录和恢复方式,不要依靠默认覆盖。

示例只处理第一层文件,避免递归搜索后把不同子目录的同名文件摊平到一个目录,也不把用户目录自身搬走。若业务需要保留目录树,应另行设计按相对路径归档的流程,不能简单删掉 -maxdepth 来扩展范围。

没有 GNU mv -t 时,保留单文件形式

-t 是 GNU mv 选项,其他实现未必支持。没有这个选项时,可以继续使用目标目录在末尾的单文件调用:

find /srv/uploads/user -type f -mtime +30 \
  -exec mv -i '{}' /srv/archive/user/ \;

这条命令会递归查找,执行前仍要决定是否增加第一层限制,以及怎样处理同名文件。只想修语法错误时,没有必要为批量化引入未经检查的范围变化。

文件移动会改变原路径,跨文件系统时还可能涉及复制后删除。使用前保存文件与原路径对应关系;需要恢复时按该对应关系移回,遇到原位置已有新文件先处理冲突,不能再次批量覆盖。

成功标准是没有 -exec 语法错误,实际移动的文件与审定名单一致,源目录与目标目录的状态都符合预期。还应检查命令退出状态和同名冲突提示;命令正常结束并不意味着所有被询问的覆盖都获准执行。