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


59

我正在使用Mac OSX。我正在尝试使用cp命令复制一些文件来生成这样的构建脚本。

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

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

Answers:


69

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

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

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

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

8
很好地解释:在这种情况下意味着什么。
Piotr Dobrogost,2014年

23
@PiotrDobrogost:在Bash和其他一些shell中,冒号是一个null实用程序(no-op)。它指定POSIX。由于它总是返回true,因此在这里用于抑制失败的退出代码cp(这是所希望的)。true可以使用内置的Shell 代替它,使其更具可读性。
丹尼斯·威廉姆森


1
这也将忽略其他错误(源/目标目录不存在,源文件存在,但不可读取,磁盘已满,只读文件系统,IO错误,cp在不被PATH莫名其妙...)
弗拉基米尔Panteleev

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

13

您正在寻找类似的东西

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

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

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

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

请注意,这种方法可能存在TOCTOU问题(例如,如果使用set -e,并且文件在[cp调用之间消失,则脚本将崩溃)。
弗拉基米尔·潘捷列夫

9

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

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

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


4
您可以使用rsync而不是cp来添加参数--ignore-missing-argsrsync -av --ignore-missing-args ./src/*/*.h ./aaa这样做的优点--ignore-errors在于,唯一被忽略的错误是与不存在的源文件有关的错误。随着--ignore-errors每一个错误被忽略,这可能是危险的。另外,还要考虑到该参数是最近才使用的,因此它在旧版本的rsync中可能不存在。
jesjimher 2015年

6

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

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

5
简单管道|始终运行,而||仅在出现错误时才运行。和true通常是二进制,而结肠:是一个内置的和不消耗一个PID。
ott-- 2015年

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

2

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

$ cpalways () { cp $1 $2 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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.