I have a root Linux shell open on my Android device, and while using cp to copy a directory, I get an error. I think I know where the error is coming from, so that is not my question.

I want to find a command that will allow me to copy everything within this directory that it can, and not just quit upon encountering an error. This is an example of what happens right now:

root@flo:/ # cp -r -v /d/* /sdcard/test/
cp '/d/TRRS'
cp: xread: Invalid argument
1|root@flo:/ #

How should I go about this?

  • 1
    What does ls -l /d/TRRS say? – Kusalananda Jan 7 '17 at 21:19
  • 1
    You may think that error is secondary but cp -r is actually meant to do what you're asking. It does accept a force option (-f) but I don't think it would overcome a fatal error like you're getting. – Julie Pelletier Jan 7 '17 at 21:21
  • @Kusalananda ls -l /d/TRRS gives: -r--r--r-- root root 0 1969-12-31 19:00 TRRS – josh798 Jan 7 '17 at 21:28
  • What do you get from ls -la /d/.? – Julie Pelletier Jan 7 '17 at 21:37
  • @JuliePelletier Here's what I get from ls -la /d/.. And just to reiterate, I'm pretty sure I know why it is failing, but I just need a command that can recover from this type of error. – josh798 Jan 7 '17 at 22:16

I had a similar problem where I needed to copy files from one directory to another and continue on errors. The idea was to copy as much as possible with the help of an operating system (in my case Debian) tool and then handle possible errors manually.

I used the hint Julie Pelletier provided in her comment to use rsync. Also I used this answer as template as I wanted to be able to analyze the copy operations which fail.

In summary the solution for your case could be

rsync --archive --itemize-changes --delete /d/ /sdcard/test/

Explanation: rsync copies the contents of your source path (/d/) to your target path (/sdcard/test/). In case the contents already exist in your target directory only the differences will be written (delta-transfer). This allows to abort and continue the process at any time. Failures will be reported without stopping the overall copy operation. rsync per default only performs a "quick check" using file size and last modified time. More criteria can be set (see below).

  • --archive specifies a set of file and directory attributes to be checked for differences
  • --itemize-changes instructs to print a summary for each file. This is very helpful to understand why a file is considered to be different by rsync. This helped me to understand failures of the copy operation. The message is rather cryptic, check the man page to understand it better.
  • --delete specifies to delete files at the target location which do not exists in your source location.

In my specific case I used a modified set of comparison criteria as I copied from one file system to another. Maybe this is helpful in your case as well:

rsync --recursive --links --safe-links --times --group --owner --devices --specials --delete --human-readable --stats --verbose --itemize-changes --progress --modify-window=3 source/ target/

The most notable changes are:

  • --safe-links in order to copy only symbolic links within the copied tree
  • No --perms (was implied by --archive) as permissions were not correctly set on the target filesystem
  • --modify-window=NUM sets a tolerance for the last modification time as those were not correctly set on the target filesystem

You can use below command

cp -r -v sourcepath destinationpath 2>/dev/null

it will nullify errors when error is trigerred

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.