Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I find myself doing this often enough that I wonder if there's a standard Unix way to do it:

% mkdir -p /TARGETDIR/relative/path/to
% cp ./relative/path/to/somefile /TARGETDIR/relative/path/to

In other words, I don't want to just copy somefile to /TARGETDIR, but actually I want to copy its entire relative path.

Is there a simpler way to do this than the two-liner above?

share|improve this question
you could use rsync to "mirror" one directory/filesystem to the other (including structure) – h3rrmiller Mar 5 '13 at 20:15
@h3rrmiller How do you propose to do that (in a way that isn't cp -R relative /TARGETDIR)? – Gilles Mar 5 '13 at 23:29
up vote 4 down vote accepted

With GNU coreutils (non-embedded Linux, Cygwin):

cp -p --parents path/to/somefile /TARGETDIR

With the POSIX tool pax (which many default installations of Linux unfortunately lack):

pax -rw -pp relative/path/to/somefile /TARGETDIR

With its traditional counterpart cpio:

find relative/path/to/somefile | cpio -p -dm /TARGETDIR

(This last command assumes that file names don't contain newlines; if the file names may be chosen by an attacker, use some other method, or use find … -print0 | cpio -0 … if available.)

Alternatively, you could make it a shell script or function.

cp_relpath () {
  mkdir -p -- "$2/$(dirname -- "$1")"
  cp -Rp -- "$1" "$2/$(dirname -- "$1")"
share|improve this answer
I'd say that cp's -p is irrelevant to the matter of the question (as well as writing scripts/programs is obviously redundant — actually I'm tempting to see another "answer" with version in Fortran, Cobol and Haskel, may be). – poige Mar 6 '13 at 13:34
@poige It isn't, but usually the option is desirable, so I include it by default. – Gilles Mar 6 '13 at 13:36
"Usually" != "really needed in question" – poige Mar 6 '13 at 13:37
So, to conclude — the only difference between our answers really worth mentioning was pax "which many default installations of Linux unfortunately lack". Entropy thanks you, чо. – poige Mar 6 '13 at 13:41
@poige Besides cp --parents, I wanted to mention pax and cpio for the non-Linux audience, and show how to do it with a function. – Gilles Mar 6 '13 at 15:47

man cp reveals --parents. So simple, yeah.

$ mkdir /tmp/myetc && cp --parents init.d/cron /tmp/myetc && find /tmp/myetc/
share|improve this answer
Note that --parents is a GNUism (it is only a long version flag). – vonbrand Mar 5 '13 at 22:13
@vonbrand, thanks, CO. – poige Mar 5 '13 at 22:26

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.