Monday, November 26, 2007

Use of --parents flag in mkdir and cp

Occasionally, you want to create a directory structure several levels deep.
For example, /home/peter/status/2007/november.

Your first attempt may be something like this:
$ mkdir /home/peter/status/2007/november
mkdir: cannot create directory `/home/peter/status/2007/november':
No such file or directory

The problem is that the intermediate directories (status and 2007) do not exist.

The following will work, but it is quite clumsy.
$ cd /home/peter; mkdir status
$ cd status; mkdir 2007
$ cd 2007; mkdir november

A much shorter way is simply:
$ mkdir --parents /home/peter/status/2007/november

With the --parents option, mkdir will actually create the intermediate parent directories if needed.

-p is the short equivalent of --parent for the mkdir command.

When the time comes to create the december directory, you can issue this:
$ mkdir -p /home/peter/status/2007/december

Although you have specified the -p (--parents) option, and the parent
directory structure already exists, it will quietly create the december
directory below it. This is just what we expect.

To check your results, do a ls -R (recursively list the directory)
$ cd /home/peter; ls -R status

december november



Let's create a file in /home/peter/status/2007/november.
 $ touch /home/peter/status/2007/november/nov12.txt

The above will create an empty file named nov12.txt.

Next, we will copy the nov12.txt file like this:
$ cd /home/peter
$ cp --parents status/2007/november/nov12.txt /home/peter/tmp

The --parents flag will cause the full path to be copied to tmp ("status/2007/november/nov12.txt")

$ cd /home/peter/tmp/
$ ls -R status



How is cp --parents different from cp -r (recursive copy)?

$ cd /home/peter
$ cp -r status /home/peter/tmp

The recursive copy will have copied everything under status (including the contents of the december directory).

ls -R /home/peter/tmp/status

december november




Anonymous said...

There missing something:

cp --parents status/2007/november/nov12.txt

-> cp: missing destination file operand after 'status/2007/november/nov12.txt'

Peter Leung said...

The cp command takes a "from-file" and a "to-file". You need to specify a "to-file".
cp --parents status/2007/november/nov12.txt somenewfile.txt

Please make sure that you can read the example in the original post in its entirety.


Anonymous said...

Nice article man. Very useful to a student of *nix.


Anonymous said...

Useful! Thanks

Little monkey said...


is it possible to use the -p option to make a parent directory whilst using cp in an shell script

when I do cp -p 'files' 'new_directory'

I get the error

"cp: target 'new_directory' is not a directory"

many thanks :-)


Unknown said...

--parents option for 'cp' command is useful, thank you!

Anonymous said...

Very helpful. Thank you.

lyndor said...

You can simply use the alias -p instead of --parents:
mkdir -p /../../../
cp -p ... ...