Add '-L' option for `cp`

Fixes #16555

Original docker `cp` always copy symbol link itself instead of target,
now we provide '-L' option to allow docker to follow symbol link to real
target.

Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
This commit is contained in:
Zhang Wei 2015-10-01 15:56:39 +08:00 committed by Tibor Vass
parent 0eb79491dd
commit 92d0c4bc45
2 changed files with 107 additions and 98 deletions

View File

@ -10,81 +10,79 @@ parent = "smn_cli"
# cp # cp
Usage: docker cp [OPTIONS] CONTAINER:PATH LOCALPATH|- Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH | -
docker cp [OPTIONS] LOCALPATH|- CONTAINER:PATH docker cp [OPTIONS] SRC_PATH | - CONTAINER:DEST_PATH
Copy files/folders between a container and the local filesystem Copy files/folders between a container and the local filesystem
--help=false Print usage -L, --follow-link=false Always follow symbol link in SRC_PATH
--help=false Print usage
In the first synopsis form, the `docker cp` utility copies the contents of The `docker cp` utility copies the contents of `SRC_PATH` to the `DEST_PATH`.
`PATH` from the filesystem of `CONTAINER` to the `LOCALPATH` (or stream as You can copy from the container's file system to the local machine or the
a tar archive to `STDOUT` if `-` is specified). reverse, from the local filesystem to the container. If `-` is specified for
either the `SRC_PATH` or `DEST_PATH`, you can also stream a tar archive from
`STDIN` or to `STDOUT`. The `CONTAINER` can be a running or stopped container.
The `SRC_PATH` or `DEST_PATH` be a file or directory.
In the second synopsis form, the contents of `LOCALPATH` (or a tar archive The `docker cp` command assumes container paths are relative to the container's
streamed from `STDIN` if `-` is specified) are copied from the local machine to `/` (root) directory. This means supplying the initial forward slash is optional;
`PATH` in the filesystem of `CONTAINER`. The command sees `compassionate_darwin:/tmp/foo/myfile.txt` and
`compassionate_darwin:tmp/foo/myfile.txt` as identical. Local machine paths can
be an absolute or relative value. The command interprets a local machine's
relative paths as relative to the current working directory where `docker cp` is
run.
You can copy to or from either a running or stopped container. The `PATH` can The `cp` command behaves like the Unix `cp -a` command in that directories are
be a file or directory. The `docker cp` command assumes all `CONTAINER:PATH`
values are relative to the `/` (root) directory of the container. This means
supplying the initial forward slash is optional; The command sees
`compassionate_darwin:/tmp/foo/myfile.txt` and
`compassionate_darwin:tmp/foo/myfile.txt` as identical. If a `LOCALPATH` value
is not absolute, is it considered relative to the current working directory.
Behavior is similar to the common Unix utility `cp -a` in that directories are
copied recursively with permissions preserved if possible. Ownership is set to copied recursively with permissions preserved if possible. Ownership is set to
the user and primary group on the receiving end of the transfer. For example, the user and primary group at the destination. For example, files copied to a
files copied to a container will be created with `UID:GID` of the root user. container are created with `UID:GID` of the root user. Files copied to the local
Files copied to the local machine will be created with the `UID:GID` of the machine are created with the `UID:GID` of the user which invoked the `docker cp`
user which invoked the `docker cp` command. command. If you specify the `-L` option, `docker cp` follows any symbolic link
in the `SRC_PATH`.
Assuming a path separator of `/`, a first argument of `SRC_PATH` and second Assuming a path separator of `/`, a first argument of `SRC_PATH` and second
argument of `DST_PATH`, the behavior is as follows: argument of `DEST_PATH`, the behavior is as follows:
- `SRC_PATH` specifies a file - `SRC_PATH` specifies a file
- `DST_PATH` does not exist - `DEST_PATH` does not exist
- the file is saved to a file created at `DST_PATH` - the file is saved to a file created at `DEST_PATH`
- `DST_PATH` does not exist and ends with `/` - `DEST_PATH` does not exist and ends with `/`
- Error condition: the destination directory must exist. - Error condition: the destination directory must exist.
- `DST_PATH` exists and is a file - `DEST_PATH` exists and is a file
- the destination is overwritten with the contents of the source file - the destination is overwritten with the source file's contents
- `DST_PATH` exists and is a directory - `DEST_PATH` exists and is a directory
- the file is copied into this directory using the basename from - the file is copied into this directory using the basename from
`SRC_PATH` `SRC_PATH`
- `SRC_PATH` specifies a directory - `SRC_PATH` specifies a directory
- `DST_PATH` does not exist - `DEST_PATH` does not exist
- `DST_PATH` is created as a directory and the *contents* of the source - `DEST_PATH` is created as a directory and the *contents* of the source
directory are copied into this directory directory are copied into this directory
- `DST_PATH` exists and is a file - `DEST_PATH` exists and is a file
- Error condition: cannot copy a directory to a file - Error condition: cannot copy a directory to a file
- `DST_PATH` exists and is a directory - `DEST_PATH` exists and is a directory
- `SRC_PATH` does not end with `/.` - `SRC_PATH` does not end with `/.`
- the source directory is copied into this directory - the source directory is copied into this directory
- `SRC_PATH` does end with `/.` - `SRC_PATH` does end with `/.`
- the *content* of the source directory is copied into this - the *content* of the source directory is copied into this
directory directory
The command requires `SRC_PATH` and `DST_PATH` to exist according to the above The command requires `SRC_PATH` and `DEST_PATH` to exist according to the above
rules. If `SRC_PATH` is local and is a symbolic link, the symbolic link, not rules. If `SRC_PATH` is local and is a symbolic link, the symbolic link, not
the target, is copied. the target, is copied by default. To copy the link target and not the link, specify
the `-L` option.
A colon (`:`) is used as a delimiter between `CONTAINER` and `PATH`, but `:` A colon (`:`) is used as a delimiter between `CONTAINER` and its path. You can
could also be in a valid `LOCALPATH`, like `file:name.txt`. This ambiguity is also use `:` when specifying paths to a `SRC_PATH` or `DEST_PATH` on a local
resolved by requiring a `LOCALPATH` with a `:` to be made explicit with a machine, for example `file:name.txt`. If you use a `:` in a local machine path,
relative or absolute path, for example: you must be explicit with a relative or absolute path, for example:
`/path/to/file:name.txt` or `./file:name.txt` `/path/to/file:name.txt` or `./file:name.txt`
It is not possible to copy certain system files such as resources under It is not possible to copy certain system files such as resources under
`/proc`, `/sys`, `/dev`, and mounts created by the user in the container. `/proc`, `/sys`, `/dev`, and mounts created by the user in the container.
Using `-` as the first argument in place of a `LOCALPATH` will stream the Using `-` as the `SRC_PATH` streams the contents of `STDIN` as a tar archive.
contents of `STDIN` as a tar archive which will be extracted to the `PATH` in The command extracts the content of the tar to the `DEST_PATH` in container's
the filesystem of the destination container. In this case, `PATH` must specify filesystem. In this case, `DEST_PATH` must specify a directory. Using `-` as
a directory. `DEST_PATH` streams the contents of the resource as a tar archive to `STDOUT`.
Using `-` as the second argument in place of a `LOCALPATH` will stream the
contents of the resource from the source container as a tar archive to
`STDOUT`.

View File

@ -7,87 +7,87 @@ docker-cp - Copy files/folders between a container and the local filesystem.
# SYNOPSIS # SYNOPSIS
**docker cp** **docker cp**
[**--help**] [**--help**]
CONTAINER:PATH LOCALPATH|- CONTAINER:SRC_PATH DEST_PATH|-
**docker cp** **docker cp**
[**--help**] [**--help**]
LOCALPATH|- CONTAINER:PATH SRC_PATH|- CONTAINER:DEST_PATH
# DESCRIPTION # DESCRIPTION
In the first synopsis form, the `docker cp` utility copies the contents of The `docker cp` utility copies the contents of `SRC_PATH` to the `DEST_PATH`.
`PATH` from the filesystem of `CONTAINER` to the `LOCALPATH` (or stream as You can copy from the container's file system to the local machine or the
a tar archive to `STDOUT` if `-` is specified). reverse, from the local filesystem to the container. If `-` is specified for
either the `SRC_PATH` or `DEST_PATH`, you can also stream a tar archive from
`STDIN` or to `STDOUT`. The `CONTAINER` can be a running or stopped container.
The `SRC_PATH` or `DEST_PATH` be a file or directory.
In the second synopsis form, the contents of `LOCALPATH` (or a tar archive The `docker cp` command assumes container paths are relative to the container's
streamed from `STDIN` if `-` is specified) are copied from the local machine to `/` (root) directory. This means supplying the initial forward slash is optional;
`PATH` in the filesystem of `CONTAINER`. The command sees `compassionate_darwin:/tmp/foo/myfile.txt` and
`compassionate_darwin:tmp/foo/myfile.txt` as identical. Local machine paths can
be an absolute or relative value. The command interprets a local machine's
relative paths as relative to the current working directory where `docker cp` is
run.
You can copy to or from either a running or stopped container. The `PATH` can The `cp` command behaves like the Unix `cp -a` command in that directories are
be a file or directory. The `docker cp` command assumes all `CONTAINER:PATH`
values are relative to the `/` (root) directory of the container. This means
supplying the initial forward slash is optional; The command sees
`compassionate_darwin:/tmp/foo/myfile.txt` and
`compassionate_darwin:tmp/foo/myfile.txt` as identical. If a `LOCALPATH` value
is not absolute, is it considered relative to the current working directory.
Behavior is similar to the common Unix utility `cp -a` in that directories are
copied recursively with permissions preserved if possible. Ownership is set to copied recursively with permissions preserved if possible. Ownership is set to
the user and primary group on the receiving end of the transfer. For example, the user and primary group at the destination. For example, files copied to a
files copied to a container will be created with `UID:GID` of the root user. container are created with `UID:GID` of the root user. Files copied to the local
Files copied to the local machine will be created with the `UID:GID` of the machine are created with the `UID:GID` of the user which invoked the `docker cp`
user which invoked the `docker cp` command. command. If you specify the `-L` option, `docker cp` follows any symbolic link
in the `SRC_PATH`.
Assuming a path separator of `/`, a first argument of `SRC_PATH` and second Assuming a path separator of `/`, a first argument of `SRC_PATH` and second
argument of `DST_PATH`, the behavior is as follows: argument of `DEST_PATH`, the behavior is as follows:
- `SRC_PATH` specifies a file - `SRC_PATH` specifies a file
- `DST_PATH` does not exist - `DEST_PATH` does not exist
- the file is saved to a file created at `DST_PATH` - the file is saved to a file created at `DEST_PATH`
- `DST_PATH` does not exist and ends with `/` - `DEST_PATH` does not exist and ends with `/`
- Error condition: the destination directory must exist. - Error condition: the destination directory must exist.
- `DST_PATH` exists and is a file - `DEST_PATH` exists and is a file
- the destination is overwritten with the contents of the source file - the destination is overwritten with the source file's contents
- `DST_PATH` exists and is a directory - `DEST_PATH` exists and is a directory
- the file is copied into this directory using the basename from - the file is copied into this directory using the basename from
`SRC_PATH` `SRC_PATH`
- `SRC_PATH` specifies a directory - `SRC_PATH` specifies a directory
- `DST_PATH` does not exist - `DEST_PATH` does not exist
- `DST_PATH` is created as a directory and the *contents* of the source - `DEST_PATH` is created as a directory and the *contents* of the source
directory are copied into this directory directory are copied into this directory
- `DST_PATH` exists and is a file - `DEST_PATH` exists and is a file
- Error condition: cannot copy a directory to a file - Error condition: cannot copy a directory to a file
- `DST_PATH` exists and is a directory - `DEST_PATH` exists and is a directory
- `SRC_PATH` does not end with `/.` - `SRC_PATH` does not end with `/.`
- the source directory is copied into this directory - the source directory is copied into this directory
- `SRC_PATH` does end with `/.` - `SRC_PATH` does end with `/.`
- the *content* of the source directory is copied into this - the *content* of the source directory is copied into this
directory directory
The command requires `SRC_PATH` and `DST_PATH` to exist according to the above The command requires `SRC_PATH` and `DEST_PATH` to exist according to the above
rules. If `SRC_PATH` is local and is a symbolic link, the symbolic link, not rules. If `SRC_PATH` is local and is a symbolic link, the symbolic link, not
the target, is copied. the target, is copied by default. To copy the link target and not the link,
specify the `-L` option.
A colon (`:`) is used as a delimiter between `CONTAINER` and `PATH`, but `:` A colon (`:`) is used as a delimiter between `CONTAINER` and its path. You can
could also be in a valid `LOCALPATH`, like `file:name.txt`. This ambiguity is also use `:` when specifying paths to a `SRC_PATH` or `DEST_PATH` on a local
resolved by requiring a `LOCALPATH` with a `:` to be made explicit with a machine, for example `file:name.txt`. If you use a `:` in a local machine path,
relative or absolute path, for example: you must be explicit with a relative or absolute path, for example:
`/path/to/file:name.txt` or `./file:name.txt` `/path/to/file:name.txt` or `./file:name.txt`
It is not possible to copy certain system files such as resources under It is not possible to copy certain system files such as resources under
`/proc`, `/sys`, `/dev`, and mounts created by the user in the container. `/proc`, `/sys`, `/dev`, and mounts created by the user in the container.
Using `-` as the first argument in place of a `LOCALPATH` will stream the Using `-` as the `SRC_PATH` streams the contents of `STDIN` as a tar archive.
contents of `STDIN` as a tar archive which will be extracted to the `PATH` in The command extracts the content of the tar to the `DEST_PATH` in container's
the filesystem of the destination container. In this case, `PATH` must specify filesystem. In this case, `DEST_PATH` must specify a directory. Using `-` as
a directory. `DEST_PATH` streams the contents of the resource as a tar archive to `STDOUT`.
Using `-` as the second argument in place of a `LOCALPATH` will stream the
contents of the resource from the source container as a tar archive to
`STDOUT`.
# OPTIONS # OPTIONS
**-L**, **--follow-link**=*true*|*false*
Follow symbol link in SRC_PATH
**--help** **--help**
Print usage statement Print usage statement
@ -102,13 +102,13 @@ If you want to copy the `/tmp/foo` directory from a container to the
existing `/tmp` directory on your host. If you run `docker cp` in your `~` existing `/tmp` directory on your host. If you run `docker cp` in your `~`
(home) directory on the local host: (home) directory on the local host:
$ docker cp compassionate_darwin:tmp/foo /tmp $ docker cp compassionate_darwin:tmp/foo /tmp
Docker creates a `/tmp/foo` directory on your host. Alternatively, you can omit Docker creates a `/tmp/foo` directory on your host. Alternatively, you can omit
the leading slash in the command. If you execute this command from your home the leading slash in the command. If you execute this command from your home
directory: directory:
$ docker cp compassionate_darwin:tmp/foo tmp $ docker cp compassionate_darwin:tmp/foo tmp
If `~/tmp` does not exist, Docker will create it and copy the contents of If `~/tmp` does not exist, Docker will create it and copy the contents of
`/tmp/foo` from the container into this new directory. If `~/tmp` already `/tmp/foo` from the container into this new directory. If `~/tmp` already
@ -120,7 +120,7 @@ will either overwrite the contents of `LOCALPATH` if it is a file or place it
into `LOCALPATH` if it is a directory, overwriting an existing file of the same into `LOCALPATH` if it is a directory, overwriting an existing file of the same
name if one exists. For example, this command: name if one exists. For example, this command:
$ docker cp sharp_ptolemy:/tmp/foo/myfile.txt /test $ docker cp sharp_ptolemy:/tmp/foo/myfile.txt /test
If `/test` does not exist on the local machine, it will be created as a file If `/test` does not exist on the local machine, it will be created as a file
with the contents of `/tmp/foo/myfile.txt` from the container. If `/test` with the contents of `/tmp/foo/myfile.txt` from the container. If `/test`
@ -137,16 +137,27 @@ If you have a file, `config.yml`, in the current directory on your local host
and wish to copy it to an existing directory at `/etc/my-app.d` in a container, and wish to copy it to an existing directory at `/etc/my-app.d` in a container,
this command can be used: this command can be used:
$ docker cp config.yml myappcontainer:/etc/my-app.d $ docker cp config.yml myappcontainer:/etc/my-app.d
If you have several files in a local directory `/config` which you need to copy If you have several files in a local directory `/config` which you need to copy
to a directory `/etc/my-app.d` in a container: to a directory `/etc/my-app.d` in a container:
$ docker cp /config/. myappcontainer:/etc/my-app.d $ docker cp /config/. myappcontainer:/etc/my-app.d
The above command will copy the contents of the local `/config` directory into The above command will copy the contents of the local `/config` directory into
the directory `/etc/my-app.d` in the container. the directory `/etc/my-app.d` in the container.
Finally, if you want to copy a symbolic link into a container, you typically
want to copy the linked target and not the link itself. To copy the target, use
the `-L` option, for example:
$ ln -s /tmp/somefile /tmp/somefile.ln
$ docker cp -L /tmp/somefile.ln myappcontainer:/tmp/
This command copies content of the local `/tmp/somefile` into the file
`/tmp/somefile.ln` in the container. Without `-L` option, the `/tmp/somefile.ln`
preserves its symbolic link but not its content.
# HISTORY # HISTORY
April 2014, Originally compiled by William Henry (whenry at redhat dot com) April 2014, Originally compiled by William Henry (whenry at redhat dot com)
based on docker.com source material and internal work. based on docker.com source material and internal work.