こんにちは、フルスタックエンジニアのryuです。
Linuxでファイルを複製したい。
そんな時は、cpコマンドを使います。
cpは基本的なコマンドですが、同名ファイルを上書きする点に注意が必要です。
この記事では、ファイルとディレクトリのコピー方法、上書き確認、属性の保持、隠しファイルを含めたコピーまで解説します。
cpコマンドとは?¶
cpはcopyに由来し、ファイルやディレクトリを複製するコマンドです。
基本書式は以下です。
cp [オプション] コピー元 コピー先
コピーと移動の違い¶
cpを実行しても、コピー元はそのまま残ります。
元のファイルを別の場所へ移したり、名前を変更したりする場合はmvを使います。
cp:コピー元を残して複製する
mv:移動または名前変更を行う
複製はcp、移動や名前変更はmvと覚えましょう。
実行前に確認すること¶
コピー前に、現在地とコピー元を確認します。
pwd
ls -l test1.txt
コピー先に同名ファイルがあるかも確認してください。
ls -l test2.txt
オプションなしのcpでは、コピー先のファイルが存在すると内容を上書きします。
ファイルをコピーする¶
まずは、1つのファイルを別の名前でコピーします。
練習用のファイルを作成して確認しましょう。
別の名前でコピーする¶
以下のコマンドを実行します。
echo "test" > test1.txt
cp test1.txt test2.txt
コピー後の内容を確認します。
cat test2.txt
test

test2.txtが存在しなければ、新しいファイルとして作成されます。
すでに存在する場合は、基本的に内容が上書きされます。
ディレクトリの中へコピーする¶
コピー先にディレクトリを指定すると、その中へ同じファイル名でコピーされます。
mkdir testdir
cp test1.txt testdir/
コピーされたか確認します。
ls -l testdir/

末尾に/を付けると、ディレクトリ指定が分かりやすくなります。
GNU cpでは、-tを使ってコピー先を先に指定する方法もあります。
cp -t testdir/ test1.txt test2.txt
複数のファイルをまとめてコピーする¶
複数ファイルを指定する場合、最後の引数は既存のディレクトリにします。
cp file1.txt file2.txt file3.txt backup/
ワイルドカードも使えます。
cp *.log backup/
実行前に、何が対象になるのか確認しましょう。
printf '%s\n' *.log
ディレクトリをコピーする¶
ディレクトリをコピーする場合は、-rまたは-Rを使います。
オプションなしでは、ディレクトリを省略したというエラーになります。
ディレクトリごとコピーする¶
testdirをtestdir2としてコピーします。
cp -r testdir testdir2
コピー先のtestdir2が存在しなければ、新しいディレクトリとして作成されます。
find testdir2 -maxdepth 2 -print

既存ディレクトリへコピーする¶
コピー先が存在すると、その中へコピー元のディレクトリが作成されます。
mkdir backup
cp -r testdir backup/
結果は次の構造です。
backup/
└── testdir/
└── test1.txt
backupの直下へtestdirの中身だけを配置したい場合は、次の方法を使います。
cp -a testdir/. backup/
隠しファイルを含めて中身だけコピーする¶
次の書き方では、.から始まる隠しファイルが対象になりません。
cp -r testdir/* backup/
設定ファイルを含めてコピーする場合は、testdir/.を指定します。
cp -a testdir/. backup/
-aは、ディレクトリを再帰的にコピーし、可能な範囲で属性やシンボリックリンクも保持します。
上書きを防ぎながらコピーする¶
cpで最も注意したいのが、既存ファイルの上書きです。
重要なファイルでは、コピー先を確認してから実行しましょう。
-iで上書き前に確認する¶
-iを付けると、既存ファイルを上書きする前に確認が表示されます。
cp -i test1.txt test2.txt
cp: overwrite 'test2.txt'?
上書きする場合はy、中止する場合はnを入力します。
手作業で重要な設定ファイルをコピーするときに便利です。
--backupで上書き前のファイルを残す¶
GNU cpでは、--backupを使うと上書き前のファイルを別名で残せます。
cp --backup=numbered test1.txt test2.txt
既存のtest2.txtは、次のような名前で保存されます。
test2.txt.~1~
上書き前の状態へ戻す可能性がある場合に役立ちます。
-uで新しいファイルだけコピーする¶
-uは、コピー元がコピー先より新しい場合や、コピー先が存在しない場合にコピーします。
cp -u test1.txt test2.txt

更新日時を基準にし、内容自体は比較しません。
厳密な同期や大量ファイルの転送には、rsyncの利用も検討しましょう。
属性を保持してコピーする¶
通常のcpでは、コピー先の所有者や時刻などがコピー元と同じにならない場合があります。
バックアップや設定移行では、どの属性を保持するかが重要です。
-pで基本属性を保持する¶
-pを付けると、可能な範囲でモード、所有者、タイムスタンプを保持します。
cp -p source.conf backup.conf
一般ユーザーでは、所有者を保持できない場合があります。
コピー後にstatで確認しましょう。
stat source.conf backup.conf
-aでディレクトリ構造を保持する¶
ディレクトリを属性ごと複製する場合は、-aが便利です。
cp -a project/ project-backup/
-aはarchiveの略で、再帰コピーに加えて、シンボリックリンクや属性を可能な範囲で保持します。
単に中身を複製するだけなら-r、バックアップに近い形で保持したいなら-aと考えると分かりやすいです。
コピー内容を確認するオプション¶
コピー対象が多い場合は、何を処理したのか表示すると確認しやすくなります。
ここでは-vと--parentsを紹介します。
-vでコピーしたファイルを表示する¶
-vはverboseの略で、処理した内容を表示します。
cp -v test1.txt test2.txt
'test1.txt' -> 'test2.txt'

ディレクトリのコピーでも利用できます。
cp -av project/ project-backup/
--parentsでパス構造を残す¶
GNU cpでは、--parentsを使うとコピー元のパス構造をコピー先へ作成できます。
mkdir backup
cp --parents config/nginx/app.conf backup/
結果は次のようになります。
backup/
└── config/
└── nginx/
└── app.conf
階層を残して設定ファイルを収集する場合に便利です。
cpコマンドでよくあるエラー¶
エラーが出た場合は、メッセージとパスを確認します。
すぐにsudoや-fを付けるのではなく、原因を切り分けましょう。
omitting directory¶
ディレクトリへ-rまたは-Rを付けていない場合に表示されます。
cp: -r not specified; omitting directory 'testdir'
次のように実行します。
cp -r testdir backup/
属性も保持したい場合は-aを使います。
cannot stat¶
コピー元が見つからない場合に表示されます。
cp: cannot stat 'test.txt': No such file or directory
現在地とファイル名を確認してください。
pwd
ls -la
Permission denied¶
コピー元を読み取れないか、コピー先へ書き込めない可能性があります。
ls -l source.txt
ls -ld destination/
id
必要な権限や所有者を確認し、安易にchmod 777へ変更しないようにしましょう。
cpを使うときの注意点¶
コピー後に、必要なファイルや属性を確認します。
コピー後の確認まで行いましょう。
コピー後に内容を比較する¶
小さなテキストファイルなら、diffで比較できます。
diff -u test1.txt test2.txt
差がなければ、通常は何も表示されません。
チェックサムで確認する方法もあります。
sha256sum test1.txt test2.txt
大量コピーではrsyncも検討する¶
cpはローカルでの単純なコピーに向いています。
中断後の再実行、差分転送、除外指定、進捗確認が必要ならrsyncの方が扱いやすい場合があります。
エンジニアとして10年以上Linuxを扱っていますが、設定を上書きするときは、コピー前のファイルを残し、コピー後に差分を確認します。
コマンドがエラーにならなかったことだけで、作業完了と判断しないことが大切です。
cpコマンドの使い方まとめ¶
ファイルを別名でコピーする場合は、以下のように実行します。
cp test1.txt test2.txt
ディレクトリは-rまたは-aでコピーします。
cp -r testdir testdir2
cp -a testdir/. backup/
上書き前に確認する場合は-i、処理内容を表示する場合は-vを使います。
cp -iv source.txt destination.txt
コピー先の存在、階層、隠しファイル、保持する属性を確認してから実行しましょう。
Linuxのファイル操作を練習したい方へ¶
InfraAcademyでは、ブラウザ上のLinux環境でファイルの作成、コピー、移動、削除を練習できます。
相対パスと絶対パスから確認したい方は、相対パスと絶対パスの違いも参考にしてください。
サーバー運用やバックアップまで学びたい方は、Linux中級講座がおすすめです。