I'm using Mac OS X. I'm trying to copying some files with cp command for a build script like this.

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

But this command fires an error if there is no .h file in ./src directory. How to make the command don't fire the error? (silent failure) The error makes build result fail, but I just want to copy when only there are some header file.

6 Answers 6


If you're talking about the error message, you can suppress that by sending it to the bit bucket:

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

If you want to suppress the exit code and the error message:

cp ./src/*/*.h ./aaa 2>/dev/null || :
  • 18
    It would be nice to explain what : means in this context. Feb 10, 2014 at 15:35
  • 33
    @PiotrDobrogost: In Bash and some other shells the colon is a null utility (no-op). It's specified by POSIX. Since it always returns true, it's used here to suppress the exit code of a failed cp (should that be desired). The shell builtin true could be used instead and would be more readable. Feb 10, 2014 at 15:46
  • 2
    This will also ignore other errors (source/destination directory doesn't exist, source file exists but is not readable, disk full, read-only filesystem, IO error, cp not being in PATH somehow...) Oct 24, 2018 at 19:32
  • syntax error near unexpected token `||'
    – thang
    Jul 24, 2019 at 20:53

You're looking for something along the lines of

if [ -e file ]
 then cp file /somewhere

(Unfortunately, the -f option is not the droid you're looking for.)

If you want to match a glob, that won't work; use find instead, e.g.:

find ./src -name \*.h -exec cp {} ./destination \;
  • Note that there is a potential TOCTOU issue with such an approach (e.g. if you use set -e, and the file disappears between the [ and the cp invocations, your script will crash). Oct 24, 2018 at 19:34

Old question, but might still be relevant for others.
If you don't need to use cp, you could try with rsync.
To copy all files from a source to a destination directory, run:

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

Rsync comes with most Unix-like systems such as Linux, Mac OS X or FreeBSD.

  • 5
    You could use rsync instead of cp, adding the parameter --ignore-missing-args: rsync -av --ignore-missing-args ./src/*/*.h ./aaa This has the advantage over --ignore-errors that the only errors ignored are those related to source files not existing. With --ignore-errors every error is ignored, which may be dangerous. Also, take into account that this parameter is fairly recent, so it might not be present in old versions of rsync.
    – jesjimher
    Oct 15, 2015 at 10:18
  • what if the source directory doesn't exist?
    – Arrrow
    Jun 18, 2020 at 7:37
  • 1
    I don't think that should be the responsibility of rsync to be honest. Rather, you can check upfront if the source directory exists, e.g. [ -d /path/to/source ] && rsync -avzh --ignore-errors /path/to/source /path/to/destination
    – mre
    Jun 18, 2020 at 11:30

Piping the result to true ensures that the command will always succeed. I have tried this on Linux but not on any Mac OS:

cp ./src/*/*.h ./aaa | true
  • 9
    The simple pipe | is always run while || is only done in case of an error. And true is usually a binary while the colon : is a builtin and doesn't consume a PID.
    – ott--
    Feb 6, 2015 at 18:16
  • 1
    A bash script on MacOS - Yosemite containing "cp ./src/*/*.h ./aaa" command does not error out if the .h files do not exist.
    – Vivek
    Feb 21, 2015 at 7:29
  • Simple, readable, and working. This is exactly what I needed, thanks mate. Jul 8 at 23:36

You could force the correct error status. With a function:

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

Given the following:

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

Regular copy will return an error. It will return an exit status of 1.

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

If we use the cpalways() function above, any errors will be hidden:

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

This works

$(cp ./src/*/*.h ./aaa | true)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.