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

cp ./src/*/*.h ./aaa


但是此命令如果./src目录中没有.h文件,则会触发错误。
如何使命令不触发错误? (静默失败)错误使构建结果失败,但是我只想在只有一些头文件的情况下进行复制。

#1 楼

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

cp ./src/*/*.h ./aaa 2>/dev/null


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

cp ./src/*/*.h ./aaa 2>/dev/null || :


评论


在上下文中解释什么是很好的。

–彼得·多布罗格斯特(Piotr Dobrogost)
2014-2-10 15:35

@PiotrDobrogost:在Bash和其他一些shell中,冒号是一个null实用程序(no-op)。由POSIX指定。由于它始终返回true,因此在此处用于禁止出现故障的cp的退出代码(这是所希望的)。可以使用内置有true的shell来代替它,并且更具可读性。

–丹尼斯·威廉姆森
2014年2月10日15:46

有关更多信息:–“:”(冒号)GNU Bash内置的目的是什么?

–彼得·多布罗格斯特(Piotr Dobrogost)
2014年2月10日15:49

这也会忽略其他错误(源/目标目录不存在,源文件存在但不可读,磁盘已满,只读文件系统,IO错误,cp不在路径中cp ...)

–弗拉基米尔·潘捷列夫(Vladimir Panteleev)
18-10-24在19:32

意外标记'||'附近的语法错误

–thang
19年7月24日在20:53

#2 楼

您正在寻找符合以下条件的东西

if [ -e file ]
 then cp file /somewhere
fi


(不幸的是,-f选项不是您要查找的机器人。)

如果您想匹配一个glob,那是行不通的;请改用find,例如:

find ./src -name \*.h -exec cp {} ./destination \;


评论


请注意,这种方法可能存在TOCTOU问题(例如,如果您使用set -e,并且文件在[和cp调用之间消失了,则脚本将崩溃)。

–弗拉基米尔·潘捷列夫(Vladimir Panteleev)
18-10-24在19:34

#3 楼

旧问题,但可能与其他问题有关。
如果不需要使用cp,可以尝试使用rsync。
要将所有文件从源复制到目标目录,请运行:

rsync -avzh --ignore-errors /path/to/source /path/to/destination


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

评论


您可以使用rsync而不是cp,添加参数--ignore-missing-args:rsync -av --ignore-missing-args ./src/*/*.h ./aaa与--ignore-唯一被忽略的错误是与源文件不相关的错误。使用--ignore-errors会忽略每个错误,这可能很危险。另外,还要考虑到该参数是最近才使用的,因此它在旧版本的rsync中可能不存在。

–jesjimher
15-10-15在10:18



如果源目录不存在怎么办?

–错误
20年6月18日在7:37

老实说,我认为这不是rsync的责任。相反,您可以预先检查源目录是否存在,例如[-d / path / to / source] && rsync -avzh --ignore-errors / path / to / source / path / to / destination

–mre
20年6月18日在11:30

#4 楼

将结果传递到true可以确保命令将始终成功。我已在Linux上尝试过此操作,但未在任何Mac OS上尝试过此操作:

cp ./src/*/*.h ./aaa | true


评论


简单的烟斗|总是在||时运行仅在出现错误的情况下执行。而true通常是二进制,而冒号:是内置的,并且不使用PID。

– ott--
15年2月6日在18:16

如果.h文件不存在,则MacOS-Yosemite上包含“ cp ./src/*/*.h ./aaa”命令的bash脚本不会出错。

– Vivek
15年2月21日在7:29

#5 楼

您可以强制正确的错误状态。具有以下功能:

$ cpalways () { cp   2>/dev/null ; return 0 ; }


鉴于以下情况:

$ ls foo bar baz
ls: baz: No such file or directory
bar foo


常规副本将返回错误。它将返回退出状态1。

$ cp baz bar ; echo $?
cp: baz: No such file or directory
1


如果使用上面的cpalways()函数,则任何错误都将被隐藏:

$ cpalways baz bar ; echo $?
0
$ cpalways foo bar ; echo $?
0
$ cpalways baz bar ; echo $?
0