cp コマンド
目次
概要
cp - ディレクトリやファイルをコピーするコマンドライン
cp [OPTION]... [-T] SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY cp [OPTION]... -t DIRECTORY SOURCE...
対象バージョン
- RHEL 10 : GNU cp 9.5
- Ubuntu 24.04 : GNU cp 9.4
説明
ファイルからファイルへのコピー
ファイルやディレクトリをコピーします。下記は fileA.txt
ファイルを fileB.txt
にコピーする例です。コピー先は無ければ作成され、あれば上書きされます。
$ cp fileA.txt fileB.txt
ファイルからディレクトリへのコピー
コピー先がすでに存在するディレクトリの場合、ディレクトリ配下にファイルをコピーします。コピー元ファイルは複数指定することができます。
$ mkdir backup $ cp fileA.txt fileB.txt fileC.txt backup
ディレクトリからディレクトリへのコピー(-r)
コピー元がディレクトリの場合は -r
オプションをつけます。コピー先ディレクトリが存在しない場合は作成され、存在する場合はその配下にコピーされます。
$ cp -r src-dir dst-dir
上書き確認(-i)
誤ってファイルを上書きしてしまうのを防ぐには -i
オプションをつけます。ファイルを上書きする際に確認プロンプトが表示されます。
$ cp -i fileA fileB cp: overwrite 'fileB'? y
常に確認付きで実行するために、.bashrc
などに下記を追加することもあります。
alias cp='cp -i'
属性もコピーする(-p, -a)
通常のコピーは、ファイルの所有者やタイムスタンプなどが変更されますが、-p
オプションをつけると所有者やタイムスタンプが維持されます。
$ cp -rp src backup
また、-a
オプションをつけると、-p
で維持されるものに加え、ハードリンクや SELinux のセキュリティ情報などもすべて維持されます。
$ cp -ra src backup
オプション
確認
- -i, --interactive
- コピー先ファイルを上書きする際に確認プロンプトを表示します。
-n
オプション指定時は無視されます。
階層構造の再帰コピー
- -R, -r, --recursive
- ディレクトリをコピーする際に指定します。ディレクトリの階層構造を再帰的にコピーします。
- --parents
- コピー元ファイルの親ディレクトリの階層構造を保ったままコピーします。下記の例で通常は
httpd.conf
がrootBackup
の直下にコピーされますが、--parents
を指定すると/etc/httpd/conf
のディレクトリ階層構造を保ったままコピーされます。$ mkdir ./rootBackup $ cp --parents /etc/httpd/conf/httpd.conf ./rootBackup $ find ./rootBackup -name "httpd.conf" ./rootBackup/etc/httpd/conf/httpd.conf
バックアップ
- --backup[=CONTROL]
- バックアップ先にすでに同名のファイルが存在する場合、古いファイルを末尾に
~
をつけてバックアップを残します。下記の例では2回バックアップを行っていますが、1回目のバックアップ時のファイルがfileA~
として残されています。$ mkdir dirA # dirAを作成 $ echo "AAA" > dirA/fileA # fileAを作成 $ cp -rT --backup dirA dirB # 一度バックアップをとる $ echo "AAAAA" > dirA/fileA # fileAの中身を書き換える $ cp -rT --backup dirA dirB # 再度バックアップをとる $ ls -l dirB total 8 -rw-r--r-- 1 yamada yamada 6 Jul 14 22:51 fileA -rw-r--r-- 1 yamada yamada 4 Jul 14 22:51 fileA~
CONTROL
には下記のいずれかを指定します。none
: バックアップしませんsimple
: 末尾に~
をつけます。2世代前のバックアップは削除されますnumbered
:~
の代わりに.~1~
,.~2~
のような番号をつけますexisting
: 既存バックアップに.~1~
等があればnumbered
、さもなくばsimple
で動作します
- -b
--backup=existing
と同等です。- -S, --suffix=SUFFIX
--backup
オプションで作成するファイル末尾の~
を別のサフィックスに変更します。--backup=numbered
の場合はこのオプションを指定しても変更されません。$ mkdir dirA $ echo "AAA" > dirA/fileA $ cp -rT --suffix=.bak dirA dirB $ cp -rT --suffix=.bak dirA dirB $ ls -l dirB/* -rw-r--r-- 1 yamada yamada 4 Jul 15 01:05 fileA -rw-r--r-- 1 yamada yamada 4 Jul 15 01:05 fileA.bak
- -T, --no-target-directory
- コピー先フォルダの有無によるコピー動作の差異を吸収します。下記が、コピー先(
src.bak
)の有無によりコピーの動作が変わってしまう例です。$ mkdir src # srcディレクトリを作成 $ touch src/fileA.txt # fileA.txtファイルを作成 $ cp -r src src.bak # バックアップをコピーする $ find ./src.bak # バックアップが作成される ./src.bak ./src.bak/fileA.txt $ cp -r src src.bak # もう一度コピーする $ find ./src.bak # バックアップ先にsrcディレクトリができてしまった ./src.bak ./src.bak/src ./src.bak/src/fileA.txt ./src.bak/fileA.txt
-T
オプションを指定することにより、常にコピー先が存在しない場合の動作に統一することができます。$ mkdir src # srcディレクトリを作成 $ touch src/fileA.txt # fileA.txtファイルを作成 $ cp -rT src src.bak # バックアップをコピーする $ cp -rT src src.bak # もう一度コピーする $ find ./src.bak # バックアップ先にsrcは作成されない ./src.bak ./src.bak/fileA.txt
ハードリンク・シンボリックリンク
- -l, --link
- コピーする代わりにハードリンクを作成します。
$ touch fileA.txt $ cp -l fileA.txt fileB.txt $ ls -l * -rw-r--r-- 2 yamada yamada 0 Jul 16 02:28 fileA.txt -rw-r--r-- 2 yamada yamada 0 Jul 16 02:28 fileB.txt
- -s, --symbolic-link
- コピーする代わりにシンボリックリンクを作成します。
$ touch fileA.txt $ cp -s fileA.txt fileB.txt $ ls -l * -rw-r--r-- 1 yamada yamada 0 Jul 15 01:27 fileA.txt lrwxrwxrwx 1 yamada yamada 9 Jul 15 01:27 fileB.txt -> fileA.txt
- -d
- ハードリンクやシンボリックリンクをそのままコピーします。
--no-dereference --preserve=links
と同等です。$ mkdir src # コピー元ディレクトリを作成 $ cd src $ touch file.txt # 通常ファイルを作成 $ ln file.txt hlink.txt # ハードリンクファイルを作成 $ ln -s file.txt slink.txt # シンボリックリンクファイルを作成 $ cd .. $ cp -r src dst-without-d # -d オプション無しでコピー $ ls -l dst-without-d # シンボリックリンクは保たれるが、ハードリンクが切れる total 0 -rw-r--r-- 1 yamada yamada 0 Jul 16 02:37 file.txt -rw-r--r-- 1 yamada yamada 0 Jul 16 02:37 hlink.txt lrwxrwxrwx 1 yamada yamada 8 Jul 16 02:37 slink.txt -> file.txt $ cp -rd src dst-with-d # -d オプション付きでコピー $ ls -l dst-with-d # ハードリンクもシンボリックリンクも保たれる total 0 -rw-r--r-- 2 yamada yamada 0 Jul 16 02:37 file.txt -rw-r--r-- 2 yamada yamada 0 Jul 16 02:37 hlink.txt lrwxrwxrwx 1 yamada yamada 8 Jul 16 02:37 slink.txt -> file.txt
- -H
- コピー元のファイルがディレクトリに対するシンボリックリンクの場合、シンボリックリンク先のディレクトリの内容をコピーします。コマンドラインで指定したファイルのみが対象です。
- -L, --dereference
- コピー元のファイルがディレクトリに対するシンボリックリンクの場合、シンボリックリンク先のディレクトリの内容をコピーします。コマンドラインで指定したファイルのみではなく、すべてのファイルが対象です。
- -P, --no-dereference
SOURCE
がシンボリックリンクでリンク先がファイルの場合、コピーするとシンボリックリンク先のファイルの中身をコピーしますが、-P
を指定するとシンボリックリンクファイルをコピーします。下記の例では-P
をつけずにコピーしたfileC
は通常ファイルとしてコピーされていますが、-P
付きでコピーしたfileD
はシンボリックリンクとしてコピーされています。シンボリックリンク先がディレクトリの場合は-P
の有無に関わらずシンボリックリンクとしてコピーされます。$ touch fileA # fileAを作成 $ ln -s fileA fileB # シンボリックリンクfileBを作成 $ cp fileB fileC # -P オプション無しでfileCにコピー $ cp -P fileB fileD # -P オプション付きでfileDにコピー $ ls -l total 0 -rw-r--r-- 1 yamada yamada 0 Jul 14 22:30 fileA lrwxrwxrwx 1 yamada yamada 5 Jul 14 22:30 fileB -> fileA -rw-r--r-- 1 yamada yamada 0 Jul 14 22:31 fileC lrwxrwxrwx 1 yamada yamada 5 Jul 14 22:31 fileD -> fileA
- --keep-directory-symlink
- コピー元とコピー先で、実ディレクトリなのか、ディレクトリに対するシンボリックリンクなのかの差異によってコピーが失敗するのを回避するために GNU cp 9.5 で追加されたオプションの様ですが、Linux ではその効果を確認することができませんでした。Linux での使用例をご存じの方が居れば教えてください。(参考)
属性維持
- -a, --archive
- アーカイブに適したオプションでコピーします。
-dR --preserve=all
オプションと同等です。シンボリックリンク、ハードリンク、モード、所有者、タイムスタンプなどの属性情報もすべてコピーします。$ cp -ra ./src ./backup/20250720_src
- -p
- モード(パーミッション)、所有者、グループ、タイムスタンプ情報を維持します。
--preserve=mode,timestamps,ownership
と同等です。 - --preserve[=ATTR_LIST]
- モード(パーミッション)、所有者、タイムスタンプなども保持したままコピーします。
ATTR_LIST
には下記を指定します。カンマ(,
)区切りで複数指定することも可能です。mode
: モード(パーミッション)timestamps
: タイムスタンプ(更新日時)ownership
: 所有者・グループlinks
: ハードリンクの関係context
: SELinuxコンテキストxattr
: 拡張属性(ファイルシステムがサポートしている場合)all
: すべて
- --no-preserve=ATTR_LIST
ATTR_LIST
で指定した属性をコピー時に保持しません。- --attributes-only
- コピー先のファイルを新規に作成する際、ファイルの中身はコピーせず空のままとし、モード、所有者、タイムスタンプなどの属性情報のみをコピーします。下記の例では
fileB
はfileA
と同じ属性で作成されますが、中身は空になります。自作したバックアップスクリプトの評価の際に中身はコピーせず、コピー時間を短縮する際などに利用されます。$ echo "AAA" > fileA # fileAを作成 $ chmod 400 fileA # モードを400に変更 $ cp --attributes-only fileA fileB # --attributes-onlyオプションを指定してコピー $ ls -l total 4 -r-------- 1 yamada yamada 4 Jul 14 22:44 fileA -r-------- 1 yamada yamada 0 Jul 14 22:44 fileB
上書きコピー
- --remove-destination
- コピー先に既存ファイルが存在する場合、一度そのファイルを削除してからコピーします。
- --update[=UPDATE]
- コピー先に同名ファイルがすでに存在する場合の動作を指定します。
UPDATE
には下記のいずれかを指定します。all
: 常に上書きしますnone
: 常に上書きしません。警告なしにスキップしますolder
: コピー先が古い時だけ上書きします(デフォルト)
- -u
--update=older
と同等です。- -f, --force
- コピー先のファイルを開けない場合、そのファイルを一度削除してからコピーします。
-n
オプション指定時は無視されます。 - -n, --no-clobber
- コピー先のファイルが存在する場合、コピーをスキップします。警告メッセージも表示しません。GNU cp 9.5 からは非推奨とされています。
--update
も参照してください。
特殊機能
- --reflink[=WHEN]
- ファイルシステムがサポートする場合、CoW(Copy-on-Write)モードでコピーします。CoW ではディスク上のデータブロックは実コピーせず、参照だけであれば元ファイルのデータブロックを参照します。どちらかのファイルに書き込みが発生した時点でデータブロックのコピーと書き込みを行います。XFS や ZFS などで利用できます。
WHEN
には下記のいずれかを指定します。auto
: 可能であれば CoW コピーを行います。できない場合は通常コピーとなります。always
: 強制的に CoW コピーを行います。できない場合はエラーとなります。never
: CoW コピーを行いません。
- --sparse=WHEN
- スパースファイルに対する扱いを制御します。sparse は「まばら」という意味を持ちます。スパースファイルは、最初の 1MB は seek で読み飛ばされてデータの書き込みが無いなどの歯抜け領域が存在するファイルを効率的に扱う仕組みです。歯抜け部分には実際にはディスクのデータブロックを割り当てないことで、ディスクの省力化を行います。ext4 などのファイルシステムでサポートされています。
WHEN
には下記のいずれかを指定します。--sparse
を指定しない時でも--sparse=auto
の動作となるようです。auto
: コピー元がスパースファイルであればスパースファイルとしてコピーするnever
: コピー元がスパースファイルでも常に全コピーする(データブロックを消費する)always
: コピー元がスパースファイルでなくてもゼロバイト領域があればスパースファイルとしてコピーする
$ dd if=/dev/zero of=fileA bs=1M count=10 # 10Mの通常ファイルを作成 $ dd if=/dev/zero of=fileB bs=1M seek=10 count=0 # 10Mのスパースファイルを作成 $ ls -lsh file* 10M -rw-r--r-- 1 yamada yamada 10M Jul 14 23:52 fileA # ファイルサイズは両方とも10Mだが 0 -rw-r--r-- 1 yamada yamada 10M Jul 14 23:52 fileB # スパースファイルはブロックを使用していない(先頭の0) # 各オプションでコピーしてみる $ cp fileA fileA-normal $ cp --sparse=auto fileA fileA-auto $ cp --sparse=never fileA fileA-never $ cp --sparse=always fileA fileA-always $ cp fileB fileB-normal $ cp --sparse=auto fileB fileB-auto $ cp --sparse=never fileB fileB-never $ cp --sparse=always fileB fileB-always $ ls -lsh file*-* 0 -rw-r--r-- 1 yamada yamada 10M Jul 15 00:03 fileA-always # 通常ファイルでもalwaysであればスパース 10M -rw-r--r-- 1 yamada yamada 10M Jul 15 00:03 fileA-auto 10M -rw-r--r-- 1 yamada yamada 10M Jul 15 00:03 fileA-never 10M -rw-r--r-- 1 yamada yamada 10M Jul 15 00:03 fileA-normal 0 -rw-r--r-- 1 yamada yamada 10M Jul 15 00:03 fileB-always # alwaysの時はスパース 0 -rw-r--r-- 1 yamada yamada 10M Jul 15 00:03 fileB-auto # autoの時もスパース 10M -rw-r--r-- 1 yamada yamada 10M Jul 15 00:03 fileB-never # neverはスパースでなくなる 0 -rw-r--r-- 1 yamada yamada 10M Jul 15 00:03 fileB-normal # オプションを指定しない場合もスパース
- --copy-contents
- デバイスファイルなどの特殊ファイルの中身も極力コピーしようと試みます。
セキュリティ
- -Z
- コピー先ファイルの SELinux のセキュリティコンテキストをデフォルトのタイプに設定します。
- --context[=CTX]
- コピー先ファイルの SELinux のセキュリティコンテキストを指定したタイプに設定します。
情報表示
- -v, --verbose
- 実行状況を表示します。
- --debug
- デバッグ情報を出力します。
-v
オプションも付加されます。 - --help
- ヘルプメッセージを表示して終了します。
- --version
- バージョン情報を表示して終了します。
その他
- -t, --target-directory=DIRECTORY
- コピー先のディレクトリ名を引数ではなくオプションで指定します。
xargs
やfind -exec {} +
と組み合わせる際に便利です。$ touch fileA.txt fileB.txt fileC.txt $ mkdir backup $ find . -name "*.txt" | xargs cp --target-directory=backup または $ find . -name "*.txt" -exec cp --target-directory=backup {} +
- -x, --one-file-system
- コピー先が別のファイルシステムにマウントされている場合にコピーをスキップします。
- --strip-trailing-slashes
- コマンドラインの
SOURCE
に/
がある場合と無い場合で挙動が異なるため、コピー元に指定したディレクトリ名から/
を取り除いて動作を統一的にするという説明ですが、Linux ではこのオプションの効能を確認することができませんでした。シンボリックリンクファイルをコピーする際には確かに/
の有無により動作が変わるのですが、--strip-trailing-slashes
をつけても動作は変わりませんでした。誰か効能をご存じの方がいれば...。
関連項目
Copyright (C) 2025 杜甫々
初版:2025年7月20日 最終更新:2025年7月20日
https://www.tohoho-web.com/linux/cmd/cp.html