-1

I desire to copy all files inside a directory which has only these files (all are regular files - there are no directories, symlinks, etc, inside that directory) to another pre-existing directory.

The files have pretty common names like robots.txt and don't follow any specific pattern.

I tried a similar command:

cp -a "$HOME"/a "$HOME"/b 

I understand that -a is a shortcut-combo for -d (preserving mode, ownership and timestamps) and -R which orders recursive copying.

If copying is recursive, why the files aren't copied and what would be a solution?

AdminBee
  • 22,803

2 Answers2

5

Scenarios:

  1. Directory a exists but b doesn't`:

    cp -a "$HOME"/a "$HOME"/b
    

    will copy the entire directory a to a new directory b

  2. Directories a and b exist:

    cp -a "$HOME"/a "$HOME"/b
    

    will copy the directory a inside directory b. So you'll get a "$HOME"/b/a directory as a result.

  3. Directories a and b exist:

    cp -a "$HOME"/a/* "$HOME"/b
    

    will copy the contents of a inside directory b but exclude hidden files and directories. While some shells have some options to include them, here the best approach would be:

    cp -a ~/a/. ~/b/
    

    This is what I understand you want.

  • 4
    Note that the very last command would not copy hidden files. This may not be an issue in this particular case, but it may well be an issue in the general case. To solve that, enable globbing of hidden files (in bash: shopt -s dotglob, in zsh: setopt GLOB_DOTS). – Kusalananda Aug 20 '19 at 22:08
  • 3
    Change the star for a dot in the last command and it'll copy everything in a for you. See this answer for the explanation. – Chris Davies Aug 21 '19 at 06:47
  • So much time passed since I last used shell globs - I forgot I have to use them here... A trouble of being a shell scripting amateur. –  Aug 21 '19 at 08:18
  • @Kusalananda, in zsh, you'd rather use cp -a "$HOME"/a/*(D) "$HOME"/b to include hidden files rather than change a global setting. But cp -a ~/a/. ~/b/ would be best. – Stéphane Chazelas Aug 22 '19 at 18:35
0

cp safety tips:

copying a directory

Directories a and b exist:

    cp -a a b/
    cp -a -t b a

will copy the directory a into directory b.

Directory a exists but b doesn't:

    cp -a a b/
    cp -a -t b a

will generate a friendly error message

copying a file

Directory b exists

    cp -T a b

will generate a friendly error message

Directory b does not exist

   cp -T a b

will copy the file, to b


Note not all versions of cp/mv/ln have the -t or -T options, but all allow the / to ensure that the b is a directory. If they don't have these options, then there is no way to guarantee that b is not an existing directory.

  • Not all implementations of cp have the -T option. Furthermore, some implementations require /. instead of just /. For example cp -a a/. b rather than cp -a a/ b. (And all implementations handle it, so there's no harm including the trailing dot on the source directory.) – Chris Davies Aug 21 '19 at 14:21
  • I have already added a note about -T not being in all implementations. – ctrl-alt-delor Aug 22 '19 at 13:36
  • Yes... but on that same note, just / on its own also doesn't work everywhere, but /. (with that trailing dot) does. – Chris Davies Aug 22 '19 at 15:27
  • @roaima can you edit the answer. – ctrl-alt-delor Aug 22 '19 at 18:15