当源文件不存在时,如何让“cp”命令不触发错误?

Eon*_*nil 84 shell copy

我正在使用 Mac OS X。我正在尝试使用 cp 命令为这样的构建脚本复制一些文件。

cp ./src/*/*.h ./aaa
Run Code Online (Sandbox Code Playgroud)

但是如果 ./src 目录中没有 .h 文件,这个命令会触发一个错误。如何使命令不触发错误?(无声失败)错误使构建结果失败,但我只想在只有一些头文件时复制。

Den*_*son 105

如果您正在谈论错误消息,您可以通过将其发送到位桶来抑制它:

cp ./src/*/*.h ./aaa 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

如果要取消退出代码和错误消息:

cp ./src/*/*.h ./aaa 2>/dev/null || :
Run Code Online (Sandbox Code Playgroud)

  • @PiotrDobrogost:在 Bash 和其他一些 shell 中,冒号是一个空实用程序(无操作)。它是由 [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/) [指定](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#colon)。因为它总是返回 true,所以它在这里用来抑制失败的 `cp` 的退出代码(应该是需要的)。可以改用 shell 内置的 `true`,这样会更易读。 (28认同)
  • 在这种情况下解释`:` 的含义会很好。 (14认同)
  • 这也将忽略其他错误(源/目标目录不存在,源文件存在但不可读,磁盘已满,只读文件系统,IO 错误,`cp` 不知何故不在`PATH` 中......) (2认同)

Bra*_*man 16

你正在寻找类似的东西

if [ -e file ]
 then cp file /somewhere
fi
Run Code Online (Sandbox Code Playgroud)

(不幸的是,该-f选项不是您正在寻找的机器人。)

如果你想匹配一个 glob,那是行不通的;使用find代替,例如:

find ./src -name \*.h -exec cp {} ./destination \;
Run Code Online (Sandbox Code Playgroud)


mre*_*mre 11

老问题,但可能仍然适用于其他人。
如果您不需要使用 cp,您可以尝试使用 rsync。
要将所有文件从源复制到目标目录,请运行:

rsync -avzh --ignore-errors /path/to/source /path/to/destination
Run Code Online (Sandbox Code Playgroud)

Rsync 随大多数类 Unix 系统一起提供,例如 Linux、Mac OS X 或 FreeBSD。

  • 您可以使用 rsync 而不是 cp,添加参数 `--ignore-missing-args`: `rsync -av --ignore-missing-args ./src/*/*.h ./aaa` 这比`--ignore-errors` 唯一忽略的错误是与不存在的源文件相关的错误。使用`--ignore-errors` 每个错误都会被忽略,这可能是危险的。此外,请考虑到此参数是最近才出现的,因此旧版本的 rsync 中可能不存在该参数。 (5认同)

小智 10

将结果设置为 true 可确保命令始终成功。我在 Linux 上试过这个,但在任何 Mac OS 上都没有试过:

cp ./src/*/*.h ./aaa | true
Run Code Online (Sandbox Code Playgroud)

  • 简单管道 `|` 始终运行,而 `||` 仅在出现错误时才执行。`true` 通常是一个二进制文件,而冒号 `:` 是一个内置函数,不消耗 PID。 (8认同)