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
    Commented Nov 11, 2018 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
    Commented Nov 11, 2018 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
    Commented Nov 11, 2018 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
    Commented Nov 11, 2018 at 11:59
  • @schily cpio is not a standard utility anymore.
    – Kusalananda
    Commented Nov 11, 2018 at 13:43

2 Answers 2

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
    Commented Nov 11, 2018 at 14:40
  • @schily Why don't you say what you are referring to?
    – Kusalananda
    Commented Nov 11, 2018 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
    Commented Nov 11, 2018 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
    Commented Nov 11, 2018 at 14:56
  • This is what you claim, my answer verifies that you are mistaken.
    – schily
    Commented Nov 11, 2018 at 16:03
1

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
    Commented Nov 29, 2018 at 13:36
  • Thisis why star contains a builtin find since 15 years...
    – schily
    Commented Jul 20, 2020 at 12:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .