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
 - スパースファイル に対する扱いを制御します。
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