cp 仅文件,跳过目录

cp 仅文件,跳过目录

使用 cp 从其中包含空目录的目录复制文件会导致错误返回值,从而导致我的脚本失败。

有没有办法让它跳过目录而不返回错误值?我希望错误值能够反映任何错误,但如果其中有一个空目录,则应该跳过,而不会报告为错误。

我可以只添加递归标志-r,但如果我只是不想复制目录,该怎么办?想要报告任何错误吗?

答案1

我建议您使用 rsync 而不是 cp,如果可以的话,它有选项 -m,可以排除空文件夹,例如:

rsync -am <origin> <destination>

命令解释explainshell.com

我使用 -a 选项是因为它执行了很多不错的默认操作,但如果您愿意,您也可以使用 -r 选项,它将仅设置递归模式。

[添加评论]

我不知道如何使用 cp 来做到这一点,至少手册页没有显示任何可以为您做到这一点的选项。您可能可以通过使用命令find查找要复制的文件/目录列表,然后将其传递给 cp 来实现更复杂的解决方案,但这比 rsync 复杂得多。rsync 在许多 Linux 中甚至几乎是标准配置

答案2

cp确实没有只获取文件的选项,但是狂暴说过了,你可以find和一起使用cp。事实上,这真的很简单:

# Copy only files
find /path/to/file -type f -execdir cp "{}" /dest/path ";"

或者:

# Copy everything except directories
find /path/to/file -not -type d -execdir cp "{}" /dest/path ";"

解释

find是查找所需文件的工具。在第一个选项中,我们设置-type f为仅返回常规文件。在第二个选项中,我们设置-not -type d为获取除目录之外的所有内容。find执行传递给的参数,每次用一个结果条目-execdir替换,并在找到{}时停止命令(应转义或,否则 shell 可能会扩展它)。;;\;";"

-execdir将运行以文件的文件夹作为其“工作目录”的命令,并且最好代替-exec,请查看下文。

选项-type文档:

-类型 c

文件类型为 c:

b:块(缓冲)特殊

c:字符(非缓冲)特殊

d:目录

p:命名管道(FIFO)

f:常规文件

l:符号链接;如果 -L 选项或 -follow 选项有效,则此条件永远不会成立,除非符号链接已损坏。如果要在 -L 有效时搜索符号链接,请使用 -xtype。

s:插座

D:门(Solaris)

选项-not文档:

表达式

如果 expr 为假,则为真。此字符通常也需要保护,以免被 shell 解释。

-不是表达式

与 !expr 相同,但不符合 POSIX 标准。

选项-execdir文档:

-执行命令 ;

执行命令;如果返回 0 状态,则为 true。 find 的所有后续参数都被视为命令的参数,直到遇到由 ';' 组成的参数。 字符串 '{}' 被替换为当前正在处理的文件名,无论它出现在命令 [...] 的参数中。 这两种构造可能需要转义(使用 '\')或用引号引起来,以防止它们被 shell 扩展。 为每个匹配的文件运行一次指定的命令。 该命令在起始目录中执行。使用 -exec 操作存在不可避免的安全问题;您应该改用 -execdir 选项。

-执行目录命令 ;

与 -exec 类似,但指定命令从包含匹配文件的子目录运行,这通常不是您启动 find 的目录。这是一种更安全的调用命令的方法,因为它可以避免在解析匹配文件的路径时出现竞争条件。[...] 如果您使用此选项,则必须确保您的 $PATH 环境变量未引用“。”;否则,攻击者可以通过将适当命名的文件留在您将运行 -execdir 的目录中来运行他们喜欢的任何命令。这同样适用于 $PATH 中的条目为空或不是绝对目录名的情况。

https://linux.die.net/man/1/find

相关内容