Despite the fact that this question and its accepted answer are ancient, I add my answer, because existing ones using cp either do not handle some edge cases or require interactive work. Often, cross-cases / scripting ability / portability / multiple sources do not matter, but simplicity wins in this case, and it is better to use cp directly with fewer flags (as in other answers) to reduce cognitive load, but for those other times (or for a reliable reuse function) this call function is useful and, by the way, is not bash-specific (I understand that this question was about bash, though, so it's just a bonus in this case). Some flags may be shortened (for example, using -a ), but I have explicitly included everything in a long form (with the exception of -R , see below) for an explanation. Obviously, just remove any flags if there is some feature that you donβt want (or you are on an OS other than posix, or your cp version does not handle this flag - I tested this on GNU coreutils 8.25 cp ):
mergedirs() { _retval=0 _dest="$1" shift yes | \ for _src do cp -R --no-dereference --preserve=all --force --one-file-system \ --no-target-directory "${_src}/" "$_dest" || { _retval=1; break; } done 2>/dev/null return $_retval } mergedirs destination source-1 [source-2 source-3 ...]
Explanation:
-R : has slightly different semantics from -R / --recursive on some systems (especially regarding special files in source directories), as explained in this answer--no-dereference : never follow symbolic links in SOURCE--preserve=all : save the specified attributes (default: mode, property, timestamps), if additional attributes are possible: context, links, xattr, all--force : if the existing destination file does not open, delete it and try again--one-file-system : stay in this file system--no-target-directory : treat DEST as a regular file (explained in this answer , namely: If you do a recursive copy and the source is a directory, then cp -T copies the content of the source into the destination, rather than copying the source itself. )- [with input channel from
yes ]: even with --force , in this particular recursive mode, cp still asks for each file to be scrambled, so we achieve a non-interactive output from it yes li> - [output to channel
/dev/null ]: does this disable a messy question line on cp: overwrite 'xx'? lines cp: overwrite 'xx'? - [return-val and early exit]: this ensures that the loop ends as soon as a failure occurs, and returns
1 if an error occurs
BTW:
- The Flemish new flag, which I also use with this in my system, is
--reflink=auto to create so-called βlight copiesβ (copy to write with the same speed advantages as hard linking, and the same size benefits to and in inverse proportion to how far the files will diverge in the future). This flag was adopted in recent GNU cp and does more than no-op with compatible file systems on the latest Linux kernels. YMWV-a-lot on other systems.
Rowan Thorpe May 27 '16 at 19:25 2016-05-27 19:25
source share