cp – ファイルやディレクトリをコピーするコマンド

コマンドリファレンス

cp コマンドは、ファイルやディレクトリをコピー するコマンドです。
バックアップの作成、設定ファイルの複製、ディレクトリごとのコピーなどに広く使われます。

bashについて、基本的な考え方や使い方については bash から参照ください。

構文(Syntax)

cp [オプション] コピー元 コピー先
cp [オプション] コピー元...  コピー先ディレクトリ

主なオプション一覧

オプション説明使用例
(なし)通常コピー(既存ファイルは上書き)cp file1.txt file2.txt
-i上書き前に確認cp -i file1.txt file2.txt
-f強制的に上書きcp -f file1.txt file2.txt
-n既存ファイルを上書きしないcp -n file1.txt file2.txt
-rディレクトリを再帰的にコピーcp -r dir1 dir2
-aアーカイブモード(属性を保持しつつ再帰コピー、-dpR 相当)cp -a dir1 dir2
-pパーミッション・所有者・タイムスタンプを保持cp -p file1.txt backup.txt
-uコピー元が新しい場合のみ上書きcp -u file1.txt file2.txt
-vコピーするファイルを表示cp -v file1.txt file2.txt
-lハードリンクとしてコピーcp -l file1.txt link.txt
-sシンボリックリンクとしてコピーcp -s file1.txt symlink.txt
--parentsディレクトリ階層ごとコピーcp --parents src/dir/file.txt /tmp

実行例

ファイルをコピー

cp file.txt backup.txt

上書き前に確認

cp -i file.txt backup.txt

出力例:

cp: overwrite 'backup.txt'? y

ディレクトリを再帰的にコピー

cp -r dir1 dir2

属性を保持してコピー(バックアップ向け)

cp -a /etc /backup

更新されたファイルのみコピー

cp -u report.txt /shared/

コピー内容を表示しながら実行

cp -v file.txt backup.txt

出力例:

'file.txt' -> 'backup.txt'

ディレクトリ階層を保持してコピー

cp --parents src/config/app.conf /tmp/

コピー先:

/tmp/src/config/app.conf

エラー例(ディレクトリコピー時に -r を忘れる)

cp dir1 dir2

出力例:

cp: -r not specified; omitting directory 'dir1'

よく使うオプションの実例

日常的によく使う 4 つのオプションを、実行例と出力付きで整理します。

-r:ディレクトリを再帰的にコピー

ディレクトリをコピーするには -r(または -R)が必須です。省略するとエラーになります。

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

# 複数ディレクトリをまとめてコピー先ディレクトリに入れる
cp -r dir1/ dir2/ /tmp/archive/

注意:cp -r dir1 dir2dir2 が存在しない場合は新規作成、すでに存在する場合は dir2/dir1 として入れ子になります。

-p:パーミッション・タイムスタンプ・所有者を保持

通常の cp はコピー先のファイルに umask が適用されます。-p を使うと元のファイルの属性をそのまま引き継ぎます。

# 属性を保持してバックアップ
cp -p /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

# 確認
ls -la /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
# -rw-r--r-- 1 root root 1234 Jun  1 10:00 /etc/nginx/nginx.conf
# -rw-r--r-- 1 root root 1234 Jun  1 10:00 /etc/nginx/nginx.conf.bak

設定ファイルのバックアップや、後で diff で比較したいケースに特に有効です。

-u:更新があったファイルだけコピー(差分のみ)

コピー先に同名ファイルが存在し、かつコピー元の方が新しい場合のみコピーします。定期バックアップや同期処理に役立ちます。

# src/ の更新済みファイルだけ dest/ へ反映
cp -u src/*.txt dest/

# -v と組み合わせてコピーされたファイルを確認
cp -uv src/*.txt dest/
# 'src/file_a.txt' -> 'dest/file_a.txt'
# (変更のない file_b.txt はスキップされる)

-v:コピー中のファイルを表示(進捗確認)

大量のファイルをコピーするときに -v を付けると、処理中のファイルが一覧表示されます。

# ディレクトリをコピーしながら進捗を表示
cp -rv logs/ logs_backup/
# 'logs/app.log' -> 'logs_backup/app.log'
# 'logs/error.log' -> 'logs_backup/error.log'
# 'logs/access.log' -> 'logs_backup/access.log'

-r-v の組み合わせは「どのファイルがコピーされたか」を確認したいときの定番です。

よくある失敗パターン

上書き確認なしで重要ファイルが消える

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 で中止できる

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

シンボリックリンクのコピー挙動

-r でコピーするとシンボリックリンクはリンク先の実体がコピーされます。リンク自体を保持したい場合は -a(または -d)を使います。

# シンボリックリンクの確認
ls -la mylink
# mylink -> /etc/hosts

# -r でコピー → リンク先の実体(ファイル)がコピーされる
cp -r mylink copy_of_link
ls -la copy_of_link
# -rw-r--r-- 1 user user 220 Jun  1 10:00 copy_of_link  ← 通常ファイル

# -a でコピー → シンボリックリンクがそのまま保持される
cp -a mylink copy_of_link2
ls -la copy_of_link2
# copy_of_link2 -> /etc/hosts  ← リンクが維持される

ディレクトリ構造をまるごと複製する場合は -a の方がシンボリックリンクを含む構成を正確に再現できます。

パーミッションが変わってしまう

-p を付けないと、コピー先のファイルは実行ユーザーの umask に基づいたパーミッションになります。スクリプトや設定ファイルをコピーすると実行ビットが外れることがあります。

# コピー元のパーミッション確認
ls -la deploy.sh
# -rwxr-xr-x 1 user user 512 Jun  1 10:00 deploy.sh

# -p なしでコピー → 実行ビットが失われる場合がある
cp deploy.sh /usr/local/bin/deploy.sh
ls -la /usr/local/bin/deploy.sh
# -rw-r--r-- 1 user user 512 Jun  1 10:00 /usr/local/bin/deploy.sh  ← 実行不可

# -p 付きでコピー → 実行ビットが保持される
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

スクリプトや実行ファイルをコピーする際は -p を付けるか、コピー後に chmod で権限を明示的に設定してください。

関連コマンド

  • mv : ファイルやディレクトリを移動(またはリネーム)
  • rsync : 高機能な同期・コピーコマンド(差分コピー対応)
  • install : ファイルコピー+パーミッション設定

備考

  • -a オプションは「完全なバックアップコピー」を作りたいときによく使われます。
  • シンボリックリンクやハードリンクを保持する場合は -a-d オプションが必要です。
  • 巨大なディレクトリをコピーする場合は rsync の方が効率的です。

参考

Bash玄

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

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

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

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

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

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

Bash玄をフォローする

コメント