1

How do I copy recursively a directory within the list at my-files-to-copy.txt?

cd my/source/dir
cpio --create < my-files-to-copy.txt | (cd my/dest/dir && cpio --extract)
my-files-to-copy.txt
src/main.js
src/routes/index.js
src/my-app/ # a directory with it's own child tree I want to recursively copy
6
  • 1
    cpio doesn't seem to support recursive copying like you want it to. Would you be able to use any of pax, tar, cp, rsync instead?
    – Kusalananda
    Nov 11 '18 at 10:24
  • cpio supports such a copy but with limited meta data support, see man page:schillix.sourceforge.net/man/man1/cpio.1.html - check the pass mode section. cpio however neither has a --create nor a --extract option. So how did you come to your question?
    – schily
    Nov 11 '18 at 10:38
  • @schily They are using GNU cpio which does have those options. --create is an alias for -o and --extract is an alias for -i.
    – Kusalananda
    Nov 11 '18 at 11:37
  • The pure existence of those non standard aliases to standard options can be seen that the related GNU tools are trying to create a vendor lock in. So these aliases are not helpful. On the other side, it is easy to write documentation that marks non-standard features...
    – schily
    Nov 11 '18 at 11:59
  • @schily cpio is not a standard utility anymore.
    – Kusalananda
    Nov 11 '18 at 13:43
1

I'm afraid cpio can't really do this, unless you do some extra scripting to detect the directory pathname and walk through it to extract the pathnames of all files below it, as a way of "pre-processing" your list file.

It would be far easier to use another tool, such as rsync (note the extra -r after --files-from!):

rsync -a --files-from=my-files-to-copy.txt -r my/source/dir my/dest/dir

... or pax (a standard utility):

( cd my/source/dir && pax -w ) <my-files-to-copy.txt |
( cd my/dest/dir   && pax -r )

... or with pax if you can give an absolute path to the destination directory:

( cd my/source/dir && pax -rw /my/dest/dir ) <my-files-to-copy.txt

... or BSD tar (use -T or --files-from= instead of -I with GNU tar):

tar -c -f - -C my/source/dir -I my-files-to-copy.txt |
tar -x -f - -C my/dest/dir

This is all assuming that my-files-to-copy.txt lives in the current directory and that this directory might be different from the my/source/dir directory.

5
  • Why didn't you read the cpio man page?
    – schily
    Nov 11 '18 at 14:40
  • @schily Why don't you say what you are referring to?
    – Kusalananda
    Nov 11 '18 at 14:45
  • Long before you created your answer, I pointed to the cpio man page and the exact part of the man page that contains the sample code to explan how cpio is used to copy files.
    – schily
    Nov 11 '18 at 14:54
  • @schily I saw that and I read your manual. It doesn't provide a convenient way of reading the list of files from a supplied text file though.
    – Kusalananda
    Nov 11 '18 at 14:56
  • This is what you claim, my answer verifies that you are mistaken.
    – schily
    Nov 11 '18 at 16:03
0

As mentioned before in the comments, cpio supports what you like. Use e.g.:

find src/main.js src/routes/index.js src/my-app/ | cpio -pdm my/dest/dir

The pitfall of this method is that you need to run two processes in a way that does not speed up things since find needs to stat(2) all files and cpio also needs to stat(2) all file some time later and cpio only uses a single process to do the actual copy.

...or you could do it the most efficient way using my own tool, star (the oldest free tar implementation):

star -copy -p -find src/main.js src/routes/index.js src/my-app/ my/dest/dir

This is efficient because star uses libfind in the star process, only needs to call stat(2) once per file and forks a second process that creates the new files concurrently to the main star process that reads the files.

In order to avoid a slow down from this method, both star processes share the file content and file meta data via shared memory.

BTW: you may of course replace the list of files from my examples by something like:

` cat my-file-list.txt ` 
2
  • Note that using cat my-file-list.txt will break when any of the file names contains whitespace or other special characters.
    – n.st
    Nov 29 '18 at 13:36
  • Thisis why star contains a builtin find since 15 years...
    – schily
    Jul 20 '20 at 12:09

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.