cpコマンドの使い方完全ガイド|ファイル・ディレクトリのコピー方法とオプション一覧

実務レシピ

cp(copy)は、Linux でファイルやディレクトリをコピーする最も基本的なコマンドです。単一ファイルのコピーから、別名でのコピー、複数ファイルの一括コピー、ディレクトリごとの再帰コピーまで、この記事だけで linux cp の使い方を一通り確認できます。

cp [オプション] コピー元 コピー先
cp [オプション] コピー元1 コピー元2 ... コピー先ディレクトリ/
  1. cp コマンドとは
  2. cp コマンド 用途別早見表
  3. ファイルをコピーする基本(cp コマンドの使い方)
    1. 単一ファイルをコピーする
    2. 別名でコピーする(リネームコピー)
    3. 複数ファイルをまとめてコピーする
  4. ディレクトリをコピーする(cp -r の使い方と落とし穴)
    1. スラッシュの有無による挙動の違い(macOS/BSD cp のみ該当)
    2. コピー先が既存ディレクトリだった場合の注意点
  5. cp コマンドのオプション比較表(-r・-a・-p・-i・-n・-u・-v)
  6. 上書き時の挙動と安全にコピーする方法
  7. 隠しファイル・シンボリックリンク・属性/タイムスタンプ保持の注意点
    1. 隠しファイルを含めてコピーする
    2. シンボリックリンクの扱い
    3. 属性・パーミッション・タイムスタンプを保持する
  8. 大量コピー・差分コピーは rsync を使う判断基準
  9. 自動化スクリプトでの活用
  10. コピー結果の確認コマンド
  11. トラブル時のチェックリスト
    1. 権限の問題
    2. ディスク容量の不足
    3. ディレクトリ構造の誤り
    4. 上書きの確認不足
    5. 大規模コピーの失敗
  12. よくある質問(FAQ)
    1. Q1. linux cp コマンドの基本的な使い方は?
    2. Q2. フォルダごとコピーする方法は?
    3. Q3. cp コマンドで別名(リネーム)コピーするには?
    4. Q4. rsync と cp の違いは?
    5. Q5. フォルダごとコピーする xcopy コマンドは?
    6. Q6. cp コマンドで「Permission denied」になって上書きできないときは?
  13. まとめ
    1. 関連記事:ファイル操作やバックアップの基礎をもっと学ぶ
      1. ファイル・ディレクトリ操作の基本
      2. バックアップ・同期に役立つコマンド
      3. システム管理の基礎もチェック
  14. 関連記事

cp コマンドとは

cp コマンドは、GNU coreutils に含まれる Linux/Unix 標準のファイルコピーコマンドです。「copy」の略で、指定したファイルやディレクトリを別の場所(別名)へ複製します。mv(移動)と違い、コピー元のファイルはそのまま残るのが特徴です。オプションなしで実行するとコピー先を確認せずに上書きするため、初めて使う場合はまず基本構文とオプションの意味を押さえておくと安全です。

cp コマンド 用途別早見表

まずは「何をしたいか」から逆引きできる早見表です。詳しい使い方は各見出しで解説します。

やりたいことコマンド例
ファイルを1つコピーcp file.txt backup.txt
別名(リネーム)でコピーcp report.csv report_2026.csv
複数ファイルをまとめてコピーcp file1.txt file2.txt file3.txt dest/
ディレクトリごとコピーcp -r src_dir dest_dir/
属性・タイムスタンプを保持してコピーcp -a src_dir dest_dir/
上書き前に確認するcp -i file.txt dest/
上書きせず新規ファイルだけ追加cp -n file.txt dest/
更新分だけコピー(差分)cp -u file.txt dest/
隠しファイルも含めてコピーcp -r src_dir/. dest_dir/
大量・差分コピー(同期)rsync -a src_dir/ dest_dir/

ファイルをコピーする基本(cp コマンドの使い方)

単一ファイルをコピーする

もっとも基本的な使い方は、コピー元とコピー先を指定するだけです。

cp file.txt backup.txt

# ディレクトリを指定すると、同じファイル名でその中にコピーされる
cp file.txt backup/

別名でコピーする(リネームコピー)

コピー先に既存とは異なるファイル名を指定すると、そのまま別名でコピーされます。設定ファイルの変更前バックアップや、日付付きファイル名での保存によく使われます。

# nginx.conf を別名で保存
cp nginx.conf nginx.conf.bak

# 日付を付けて別名保存
cp report.csv report_$(date +%Y%m%d).csv

複数ファイルをまとめてコピーする

コピー元を複数指定すると、最後に書いたディレクトリへまとめてコピーされます。コピー先は既存のディレクトリである必要があります。

# 個別にファイル名を指定
cp file1.txt file2.txt file3.txt backup/

# ワイルドカードでまとめて指定
cp *.txt backup/

# 複数のディレクトリをまとめて1つのコピー先に入れる
cp -r documents/ photos/ scripts/ /backup/

*.txt のようなワイルドカードは、先頭が . の隠しファイル(.env など)を展開しません。隠しファイルも含めたい場合は後述の「隠しファイルを含むコピー」を参照してください。

ディレクトリをコピーする(cp -r の使い方と落とし穴)

ディレクトリを丸ごとコピーしたいときは cp -r を使います。-r は「再帰的コピー」を意味し、ディレクトリの中身を階層ごとにコピーします。-r を付けずにディレクトリを指定するとエラーになる点に注意してください。

# ディレクトリごとコピーする(基本)
cp -r src_dir dst_dir/

# 実際の例
$ ls
src_dir backup
$ cp -r src_dir backup/
$ tree backup
backup/
└── src_dir
    ├── file1.txt
    └── file2.txt

# -r を忘れた場合のエラー
$ cp src_dir backup/
cp: -r not specified; omitting directory 'src_dir'

スラッシュの有無による挙動の違い(macOS/BSD cp のみ該当)

cp コマンドでディレクトリをコピーする際、末尾にスラッシュを付けるかどうかで結果が変わる場合があります。特にバックアップや自動スクリプトでは、意図しないディレクトリ構造を作ってしまう原因になるため注意が必要です。

Linux(GNU cp)では src_dirsrc_dir/ の挙動は同じです。スラッシュ有無で結果が変わるのは macOS(BSD cp)のみで、Linux 環境では起こりません。

# macOS(BSD cp)のみの挙動
$ cp -r source_dir/ destination_dir/
$ tree destination_dir/
destination_dir/
├── file1.txt
└── file2.txt

💡 補足
クロスプラットフォームで挙動を揃えたい場合は、明示的に cp -a src_dir backup/(スラッシュなし)と書くのがおすすめです。

コピー先が既存ディレクトリだった場合の注意点

cp -r を使うときにもう一つ重要なのが、コピー先ディレクトリが既に存在する場合の挙動です。意図しないディレクトリ構造を作ってしまうトラブルの多くはここで起こります。

$ ls
src_dir destination_dir
$ cp -r src_dir destination_dir/
$ tree destination_dir
destination_dir/
└── src_dir
    ├── file1.txt
    └── file2.txt
  • destination_dir/ が存在する場合、source_dir はその中に 新しいサブディレクトリとしてコピーされる(destination_dir/source_dir/...)。
  • 中身だけをコピーしたいなら、Linuxでは cp -r source_dir/. destination_dir/ のようにドット表記を使うか、GNU cp-T オプションを使う。
  • 上書きではなく置き換えたい場合は cp -rT source_dir destination_dirdestination_dir が既に存在していても「単なるコピー先」として扱われるため、二重構造を防げます。

cp コマンドのオプション比較表(-r・-a・-p・-i・-n・-u・-v)

実務でよく使う7つのオプションを比較します。組み合わせて使うことも多いオプションです。

オプション意味・動作用途・ポイント
-rディレクトリを再帰的にコピーディレクトリコピーの基本。属性は保持しない
-a (--archive)-dR --preserve=all 相当。属性・シンボリックリンク・タイムスタンプを保持して再帰コピーバックアップ用途で推奨。 -r の上位互換と覚えると良い
-p所有者・パーミッション・タイムスタンプを保持単一ファイルの属性を保持したいときに使う
-i (--interactive)上書き時に確認を求める誤操作防止。重要ファイルを扱うときの基本
-n (--no-clobber)既存ファイルを上書きしない上書きを避けて安全に追加コピーしたいときに使う
-f (--force)書き込み権限がなく削除できない既存ファイルも、一度削除してから強制的に上書きコピーPermission denied で失敗する上書きコピーを通したいときに使う。-i と併用すると -f が優先される
-uコピー元がコピー先より新しい場合のみコピー差分反映・簡易的な同期に便利
-v (--verbose)コピー中のファイル名を表示進捗確認やログ出力に活用。他オプションと組み合わせるのが定番

よくある組み合わせ例です。

# 上書き前に確認しながらディレクトリコピー
cp -rvi source_dir destination_dir/

# 属性を保持してバックアップ的にコピー
cp -a source_dir destination_dir/

# 更新分だけを表示しながらコピー
cp -uv src/*.txt dest/

上書き時の挙動と安全にコピーする方法

cpデフォルトでは確認なしに上書きします。コピー元とコピー先を取り違えると、既存ファイルの内容がそのまま失われるため注意が必要です。

# 危険:important.txt の内容が old_data.txt の内容で上書きされる
cp old_data.txt important.txt

# 安全:上書き前に確認する
cp -i old_data.txt important.txt
# cp: overwrite 'important.txt'? n  ← n で中止できる

# 安全:既存ファイルは上書きせずスキップする
cp -n old_data.txt important.txt

安全にコピーするための代表的な方法は次の3つです。

  • -i:上書き前に1件ずつ確認する。少数のファイルを慎重に扱いたいときに向く
  • -n:既存ファイルは無条件にスキップする。大量ファイルを追加コピーするときに向く
  • 事前に lsdiff でコピー先の状態を確認してから実行する。特に cp -r でディレクトリごと上書きする場合は、実行前に ls destination_dir で既存の有無を確認する習慣をつける

重要なファイルを扱う場合は -i を常に付けるか、alias cp='cp -i'~/.bashrc に設定しておくと安全です。

隠しファイル・シンボリックリンク・属性/タイムスタンプ保持の注意点

隠しファイルを含めてコピーする

cp -r src_dir dest_dir/ のようにディレクトリ名を指定した場合は隠しファイルも含めてコピーされますが、cp src_dir/* dest_dir/ のようにワイルドカードで展開すると、.env.gitignore など先頭が . のファイルは対象から漏れます。

# .env などの隠しファイルが漏れる
cp -r src_dir/* dest_dir/

# 隠しファイルも含めてコピーする(中身だけをコピー)
cp -r src_dir/. dest_dir/

シンボリックリンクの扱い

現在の GNU cp(coreutils)では、-r でも -a でもシンボリックリンクはリンクのまま保持されます(リンク先の実体を自動でコピーするわけではありません)。この点は誤解されやすいので、実際に確認しておきましょう。リンク先の中身を実体としてコピーしたい場合は、-r-L--dereference)を追加します。

# -r でコピー → シンボリックリンクのまま保持される(実体はコピーされない)
$ cp -r mylink copy_of_link
$ ls -la copy_of_link
lrwxrwxrwx 1 user user 10 Jun  1 10:00 copy_of_link -> target.txt  ← リンクのまま

# -a でコピーしても結果は同じ(リンクを保持)
$ cp -a mylink copy_of_link2
$ ls -la copy_of_link2
lrwxrwxrwx 1 user user 10 Jun  1 10:00 copy_of_link2 -> target.txt

# リンク先の実体をコピーしたい場合は -L を追加する
$ cp -rL mylink copy_of_link3
$ ls -la copy_of_link3
-rw-r--r-- 1 user user 220 Jun  1 10:00 copy_of_link3  ← 通常ファイル(実体)

属性・パーミッション・タイムスタンプを保持する

-p を付けない場合、所有者・タイムスタンプは実行ユーザー・実行時刻のものになり、パーミッションはコピー元のモードを umask でマスクした値になります。一般的な umask 022 では書き込み権限のみが制限され、実行ビットが外れることは通常ありません。umask 077 のように実行ビットまで削る設定の環境や、所有者・更新日時を厳密に引き継ぎたい場合に -p の効果が明確になります。

# umask 077 環境では -p なしだと実行ビットも失われる
$ umask 077
$ cp deploy.sh /usr/local/bin/deploy.sh
$ ls -la /usr/local/bin/deploy.sh
-rwx------ 1 user user 512 Jun  1 10:00 /usr/local/bin/deploy.sh  ← group/otherの権限が消える

# -p 付きでコピー → umaskの影響を受けず元のパーミッションを保持
$ cp -p deploy.sh /usr/local/bin/deploy.sh
$ ls -la /usr/local/bin/deploy.sh
-rwxr-xr-x 1 user user 512 Jun  1 10:00 /usr/local/bin/deploy.sh

ディレクトリ構造をまるごと複製する場合は、パーミッション・タイムスタンプ・シンボリックリンクをまとめて保持できる -a の方が確実です。

大量コピー・差分コピーは rsync を使う判断基準

cp はシンプルで手軽に使えますが、次のようなケースでは rsync を検討したほうが安全・高速です。

  • ファイル数が数千〜数万件など大量にある(cp は途中で失敗すると再開できない)
  • 2回目以降は変更分だけコピーしたい(差分コピー・同期)
  • リモートサーバーとの間でコピーしたい(cp はローカルのみ対応)
  • コピーの進捗表示や、途中で中断したコピーの再開が必要

逆に、少数ファイルの一時的なコピーや、スクリプトの中で完結する単純なコピーであれば cp で十分です。

比較項目cprsync
主な用途単純コピー差分・同期コピー
差分コピー❌ なし(常に上書き、-uは簡易対応)✅ 変更分のみ転送
転送経路ローカルのみローカル/リモート両対応
中断時の再開❌ 非対応✅ 対応
推奨場面一時的な複製、単発コピー定期バックアップ、大量コピー、リモート同期
# cp を使ったディレクトリコピー
cp -a source_dir/ destination_dir/

# rsync を使ったディレクトリコピー(差分対応・大量ファイル向け)
rsync -a source_dir/ destination_dir/

自動化スクリプトでの活用

cp コマンドはシェルスクリプトに組み込んで定期バックアップを自動化できます。-u を付けることで更新されたファイルのみをコピーし、処理を効率化します。

#!/bin/bash
date=$(date +%Y%m%d)
cp -u -r /data/important_files/ /backup/$date/
# crontab への追加例(毎日午前2時に実行)
0 2 * * * /path/to/backup.sh

コピー結果の確認コマンド

# コピー後に構造を確認
tree dst_dir

# ファイルの中身が一致しているか確認
diff -r src_dir dst_dir/src_dir

diff -r で「完全コピーできているか」を検証できます。

トラブル時のチェックリスト

権限の問題

  • コピー先に書き込み権限があるか確認する ls -ld destination_dir
  • 権限不足の場合は sudo を付けて実行 sudo cp -a source_dir/ destination_dir/

ディスク容量の不足

  • 空き容量が足りないとコピーは失敗する df -h
  • 必要に応じて不要ファイルを削除、もしくは別のストレージを利用する

ディレクトリ構造の誤り

  • macOS(BSD cp)では末尾スラッシュの有無で結果が変わる
  • コピー先が既に存在する場合、意図せず二重ディレクトリができていないか確認する

上書きの確認不足

  • -i オプションを付けずに実行すると、気づかないうちにファイルを上書きしてしまうことがある
  • 安全に行うには cp -rvi source_dir/ destination_dir/

大規模コピーの失敗

  • ファイル数が多い場合は cp ではなく rsync を検討 rsync -a --progress source_dir/ destination_dir/

このチェックリストを順番に確認すれば、多くの「コピーできない」「コピー結果が違う」といったトラブルを早期に解決できます。

よくある質問(FAQ)

Q1. linux cp コマンドの基本的な使い方は?

cp コピー元 コピー先 の形式で使います。ファイル1つのコピーならそのまま、ディレクトリごとコピーする場合は -r(再帰的コピー)を付けます。

# ファイルをコピー
cp file.txt backup/

# ディレクトリごとコピー
cp -r dir backup/

Q2. フォルダごとコピーする方法は?

フォルダ(ディレクトリ)を丸ごとコピーするには、cp コマンドに -r(再帰的コピー) オプションを付けます。

cp -r フォルダ名 コピー先/

# 例
cp -r project backup/

属性も保持したい場合は -a オプションを使うとより確実です。

cp -a project backup/

Q3. cp コマンドで別名(リネーム)コピーするには?

コピー先に別のファイル名を指定するだけです。移動ではなく複製なので、元のファイルはそのまま残ります。

cp config.yml config.yml.bak

Q4. rsync と cp の違いは?

rsync は「差分を検出して更新する」点が最大の強みです。バックアップやサーバー間コピー、大量ファイルのコピーには rsync -av を使うのがおすすめです。日常的な少数ファイルのコピーには cp で十分です。

Q5. フォルダごとコピーする xcopy コマンドは?

xcopyWindows でフォルダごとコピーするためのコマンドです。Linux では cp -r が対応します。

# Windows の場合
xcopy C:project D:backup /E /I /H
オプション意味
/E空フォルダも含めてコピー
/Iコピー先がフォルダであると仮定
/H隠しファイルやシステムファイルもコピー

Q6. cp コマンドで「Permission denied」になって上書きできないときは?

コピー先のファイルが読み取り専用(書き込み権限なし)の場合に起こります。-f--force)オプションを付けると、既存ファイルを一度削除してから強制的にコピーできます。

# Permission denied で失敗する例
$ cp new.conf readonly.conf
cp: cannot create regular file 'readonly.conf': Permission denied

# -f で強制的に上書きコピー
$ cp -f new.conf readonly.conf

それでも失敗する場合は、コピー先のディレクトリ自体に書き込み権限がないケースです。ls -ld でディレクトリの権限を確認するか、sudo を付けて実行してください。

まとめ

linux cp の基本は、ファイル1つのコピーもディレクトリごとのコピーも同じ構文で行えることです。ディレクトリをコピーするなら -r、属性やシンボリックリンクまで保持したいなら -a を使い、上書き確認(-i)、上書き防止(-n)、差分コピー(-u)、進捗表示(-vを目的に合わせて組み合わせることで、安全で効率的なコピーが実現できます。

隠しファイルやシンボリックリンクの扱いに注意しつつ、大規模なバックアップやリモートとの同期が必要な場合は rsync を使うことで処理速度や信頼性を高められます。コピーの仕組みを理解して使い分ければ、意図しないファイル構造や上書き事故を防ぎ、日常的な作業からシステム管理まで安心して活用できます。

関連記事:ファイル操作やバックアップの基礎をもっと学ぶ

cp コマンドでのコピーを理解したら、ファイル管理やバックアップ関連の操作も押さえておくと便利です。bash道では以下の記事で詳しく解説しています。

ファイル・ディレクトリ操作の基本

バックアップ・同期に役立つコマンド

システム管理の基礎もチェック

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする