How to test which files will be copied with the cp command?

21,435

Solution 1

I don't think GNU cp has anything to help you if you want to see what it would do without acting. If you want to log the files that were modified, you can use the -v option:

cp -puv DIRECTORYA/* DIRECTORYB >copy.log

Instead of cp, you can use rsync, which is a lot more powerful and installed almost everywhere except for low-end embedded systems (and easy to install where it isn't present by default).

rsync -aunv DIRECTORYA/* DIRECTORYB >what-would-be-done.txt

or

rsync -auv DIRECTORYA/* DIRECTORYB >copy.log

Solution 2

According to the manual page,

-u, --update
copy only when the SOURCE file is newer than the destination file or when the destination file is missing

this is a feature which combines two tests, one trivial to implement in a script (missing) and one requiring some work (newer). You could make a script which reports what is needed using comm, diff and test.

None of the standard cp utilities provide the ability to dry-run a copy operation. As suggested, rsync is the way to do this with a commonly-available utility. Of course, rsync is usually used to copy based on more criteria than just newer or missing (file size and timestamps also are used). But it can be reduced to doing just cp -u.

For non-standard utilities, there's the copy utility which I wrote (and of course still use) in the late 1980s. It was probably inspired by the make utility, since the first option I added was -n.

For the given example, it would be used like this:

$ copy -nvU DIRECTORYA/* DIRECTORYB
** copy DIRECTORYA/foo to DIRECTORYB/foo
** 1 file would be copied, 616 bytes

Further reading:

  • copy - file/directory copy utility

    -n disables the actual creation or modification of files, and (depending on the level of verboseness) shows the effect which the copy command would have.
    -u copies files only if their size or modification date differs, and links only if the link-text differs.
    -U copies only files that are newer than the destination, or that do not exist in the destination.

  • changelog entry from August 1988:

    1988-08-16    
            * src/copy/src/copy.c: added "-d" and "-n" options.
    

Solution 3

If you wanted to run cp foo*bar whatever, then run echo foo*bar whatever instead.

Share:
21,435

Related videos on Youtube

James
Author by

James

Updated on September 18, 2022

Comments

  • James
    James almost 2 years

    I'm creating a simple script that copies all files from DIRECTORYA that do not exist in DIRECTORYB. I'm doing this through the use of the cp command:

    cp -u DIRECTORYA/* DIRECTORYB
    

    What I'd like to do is also send an email to an administrator that will list the files that have been copied.

    So ideally, before I run the above command, I'd like to get the files that will be copied and store them in a variable for later use when building my email message.

    Can anybody point me in the right direction? I've looked into using grep but I don't think this can be done with the cp command?

    • ThibautRenaux
      ThibautRenaux over 9 years
      Maybe I'm misunderstanding your question, but can't you use the -v flag, to print the filenames as they are copied? Redirect that to a file or directly in a variable and use that to build your message.
    • Costas
      Costas over 9 years
      Additionally the cp command has option --attributes-only wich allow to do not copy files data, but just directory and files structure.
  • Arkadiusz Drabczyk
    Arkadiusz Drabczyk over 9 years
    But OP wants to run cp -u and he's looking for a dry-run like option for cp.
  • WinEunuuchs2Unix
    WinEunuuchs2Unix about 4 years
    I wonder if the find command couldn't be tailored to work like the cp command. I'm gonna give that a try this week. If you have any caveats in advance that would be very much appreciated.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' about 4 years
    @WinEunuuchs2Unix Sure, you can run find inside both DIRECTORYA and DIRECTORYB and compare the output. I'm sure the code to do this has been posted multiple times on this site.
  • Merlin
    Merlin almost 3 years
    rsync is great, thanks this is my preferred solution.
  • Merlin
    Merlin almost 3 years
    NOTE: rsync -aun (aka rsync --archive --update --dry-run) will print nothing, you need to add the --verbose/-v flag to get your dry run output. Maddening, but now you know (rsync version 3.2.3 protocol version 31). rsync is still awesome.