【Linux】cpコマンドでファイルやディレクトリを複製・バックアップする

目次

概要

cp(copy)コマンドは、ファイルやディレクトリを複製するための基本コマンドです。

単なるファイルの複製だけでなく、システムバックアップのために権限やタイムスタンプを完全に保持したままコピーしたり、実体データを増やさずにシンボリックリンクとして配置したりと、オプションによって多様な動作が可能です。サーバー構築や運用保守の現場で、設定ファイルのバックアップを取る際などに最も頻繁に使用されます。

仕様(引数・オプション)

構文

# ファイルを別の名前でコピー
cp [オプション] [コピー元ファイル] [コピー先ファイル]

# 複数のファイルをディレクトリへコピー
cp [オプション] [コピー元ファイル...] [コピー先ディレクトリ]

主なオプション

バックアップやリンク作成に関するオプションが充実しています。

オプション説明
-a元のファイル属性(所有者、権限、時間)や構成を可能な限り保持して再帰的にコピーします(archive)。バックアップに最適です。
-iコピー先に同名ファイルがある場合、上書きするか確認します(interactive)。
-r, -Rディレクトリを再帰的にコピーします(Recursive)。
-uコピー先ファイルが存在しない、またはコピー元より古い場合のみコピーします(update)。
-pファイルの所有者、グループ、パーミッション、タイムスタンプを保持します。
-sコピーする代わりにシンボリックリンクを作成します(symbolic-link)。
-lコピーする代わりにハードリンクを作成します(link)。
-t [ディレクトリ]コピー先のディレクトリを明示的に指定します(target-directory)。xargsと組み合わせる際に便利です。
-b上書きされるファイルのバックアップを作成します(末尾に ~ が付きます)。
-S [文字列]バックアップファイルの末尾に付ける文字列(サフィックス)を指定します。
-Lシンボリックリンクの実体をコピーします(デフォルトはリンク自体をコピー)。
-Pシンボリックリンクをリンクのままコピーします(-d-aに含まれます)。

基本の使い方

ファイルの複製

最も基本的な使い方は、ファイルを別の名前でコピーすることです。

cp production.conf production.conf.bak

実行結果イメージ:

(出力はなく、ファイルが複製されます)

ls -l production.conf*
-rw-r--r-- 1 user group 1024 Jan 15 10:00 production.conf
-rw-r--r-- 1 user group 1024 Jan 16 09:00 production.conf.bak

実践コマンド

1. 権限と構成を完全保持してディレクトリごとコピー (-a)

Webサーバーのドキュメントルートや設定ディレクトリをバックアップする場合、所有者や権限が変わると動作しなくなることがあります。-a オプションを使えば、それらを完全に維持したままコピーできます。

# /var/www/html を /var/www/html_backup に完全コピー
sudo cp -a /var/www/html /var/www/html_backup

実行結果イメージ:

ls -l /var/www/
drwxr-xr-x 2 www-data www-data 4096 Jan 01 00:00 html
drwxr-xr-x 2 www-data www-data 4096 Jan 01 00:00 html_backup

※ タイムスタンプや所有者(www-data)が維持されている点に注目してください。

2. 実体を増やさずにシンボリックリンクを作成する (-s)

巨大なデータを別の場所に配置したいが、ディスク容量を消費したくない場合、-s オプションで「ショートカットとしてのコピー」を作成できます。

# big_data.iso のシンボリックリンク link_to_data を作成
cp -s /mnt/storage/big_data.iso ./link_to_data

実行結果イメージ:

ls -l link_to_data
lrwxrwxrwx 1 user group 24 Jan 16 09:10 link_to_data -> /mnt/storage/big_data.iso

3. 引数長制限を超える大量ファイルをコピーする (xargs + -t)

数万個のファイルを cp *.log dir/ でコピーしようとすると「Argument list too long」エラーになります。これを回避するために、findls の結果をパイプで渡し、xargs-t(コピー先指定)を使って処理します。

# カレントディレクトリの全ての .log ファイルを ../log_archive/ へコピー
find . -maxdepth 1 -name "*.log" -print0 | xargs -0 cp -t ../log_archive/

find -print0xargs -0 を使うことで、ファイル名にスペースが含まれていても安全に処理できます。

カスタムポイント

  • 上書き確認 (-i):
    • alias cp='cp -i' と設定されていることが多いですが、スクリプト内で使う場合は -f(強制)や -n(上書きしない)を明示的に指定して挙動を確定させます。
  • 更新分のみコピー (-u):
    • 巨大なディレクトリを同期させる際、変更があったファイルだけをコピーして時間を短縮したい場合に使用します(ただし、本格的な同期には rsync コマンドが推奨されます)。
  • バックアップ接尾辞 (-S):
    • cp -b -S .old target.txt dest/ とすると、上書きされたファイルが target.txt.old として残ります。

注意点

  1. ディレクトリコピー時の -r 忘れ:
    • ディレクトリをコピーする際に -r(または -a)を付け忘れると、「omitting directory」というエラーが出てコピーされません。
  2. root権限が必要な属性保持:
    • 一般ユーザーが -a-p を使ってシステムファイルをコピーしようとしても、元のファイルの所有者が root などの場合、所有権の保持に失敗することがあります(Permission denied)。その場合は sudo が必要です。
  3. シンボリックリンクの扱い:
    • リンクファイルをコピーする際、デフォルトでは「リンク先の実体」を読み込んで新しいファイルとしてコピーしようとする場合があります(-L相当)。リンク自体をコピーしたい場合は -P-d-aに含まれる)が必要です。

応用

番号付きバックアップを作成する

設定ファイルを編集する前に、既存のファイルを config.conf.~1~ のように番号付きで退避させます。

# 既存の config.conf があれば config.conf.~1~ にリネームして、新規コピー
cp --backup=t config.conf /etc/app/config.conf

まとめ

cpコマンドはLinux操作の基本ですが、オプションの使い分けで安全性が大きく変わります。

  • 向く場面: ファイル複製、設定変更前のバックアップ、ディレクトリ全体の退避。
  • 変更ポイント: 完全バックアップなら -a、容量節約なら -s、大量ファイルなら -txargs
  • 注意点: ディレクトリには -r が必須。権限維持には sudo-a を併用する。

特に -a オプションは「Archive」の略で、元通りの状態でコピーできる最強のオプションです。バックアップ時はとりあえず -a を付けておくと安心です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次