Linux

Linuxコマンドを解説!~実践で役立つコピー(cp)コマンド~

龍さん

インフラエンジニア/PM/PL/チーフリーダー/ボールド歴6年

Windows環境でもLinux環境でも、ファイルやディレクトリを複製するコマンドは「cp」コマンドとなります。コピー(copy)の略なので覚えやすいですね。今回は実際の業務で多く用いられる「cp」コマンドの解説と、作業ミスをなくす複製の方法などをご紹介します。また、最後にパーミッションについても触れておりますので、この機会にパーミッションも理解してみましょう。


1.cpコマンドとは

ファイルやディレクトリを複製(コピー)するコマンドです。編集対象ファイルのバックアップ取得や、ソースファイルを複製して利用するなど、多くの業務で利用します。

1-1.コマンドの使い方

cpコマンドの基本的な使い方は、

cp△[複製元ファイル] [複製先]

となりまます。※△はスペースです。

ファイルやディレクトリを複製する場合、複製先のディレクトリに書き込み権限がない場合、「Permission denied」として書き込みエラーとなりますのでご注意ください。

1-2.cpコマンドのオプション一覧

cpコマンドのオプション一覧は、以下の通りです。

オプション意味
-a, –archive元のファイルの属性とディレクトリ構成を可能な限り保持します。
-b, –backup上書きされるファイルのバックアップを作成します。
-d, –no-dereferenceコピー先に同じ名前のファイルがあれば、確認なしで上書きします。
-f, –forceコピー先に同じ名前のファイルがあれば、確認なしで上書きします。
-i, –interactive上書きされるファイルがあれば、その可否を確認します。
-l, –linkコピーのかわりにハード・リンクを作成します。ただしディレクトリは除外します。
-P, –parents元のファイルの属性(タイムスタンプ等)を可能な限り保持します。
-rディレクトリを中身ごとコピーします。
-s, –symbolic-linkコピーするかわりにシンボリック・リンクを作成します。
-u, –update同名のファイルが存在する場合、コピー先のタイムスタンプが同じか新しいときはコピーしません。
-v, –verbose経過を表示します。
-x, –one-file-systemコピーするファイルまたはディレクトリを指定します。コピー先がディレクトリであれば、スペース区切りで複数列挙することができます。
-R, –recursiveディレクトリを再帰的にコピーする。
–helpコピー先のファイル名またはディレクトリを指定します。
Sourceコピー元のファイルやディレクトリを指定する。ワイルド・カードを使用することもできる。
Destコピー先のファイル名やディレクトリ名を指定する。ファイル名を指定した場合は新しい名前でコピーされる。
directoryコピー先のディレクトリを指定する。

1.2.cpコマンドのオプション一覧


2.コマンドの使用例

では実際にcpコマンドの使い方をご説明します。

2-1.ファイルをコピーする

①同一ディレクトリ内にコピーする

ファイル名「cptest1.txt」を同じディレクトリ内に「cptest2.txt」としてコピーします。

[engineer-club@test]$ls -l
total 4
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
[engineer-club@test]$cp cptest1.txt cptest2.txt
[engineer-club@test]$ls -l
total 8
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest2.txt
[engineer-club@test]$

実行した結果、cptest1.txtcptest2.txtとしてコピーされました。

②指定したディレクトリへコピーする

同様にcptest1.txtを「cpdir」配下にコピーします。この場合、同じファイル名でコピーする事も可能ですが、混乱を招く恐れがありますので、基本的には別名で保存するようにしましょう。ここではcptes3.txtとしてコピーします。

[engineer-club@test]$mkdir cpdir
[engineer-club@test]$ls -l
total 8
drwxrwxr-x. 2 engineer-club engineer-club 6 Apr 14 12:15 cpdir
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest2.txt
[engineer-club@test]$cp cptest1.txt cpdir/cptest3.txt
[engineer-club@test]$ls -l cpdir/
total 4
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:16 cptest3.txt
[engineer-club@test]$

実行の結果、cptest1.txtcpdir配下にcptest3.txtとしてコピーされました。

2-2.ディレクトリをコピーする

ディレクトリ「cpdir」を「cpdir2」としてコピーしてみますが、「cpdir」はディレクトリであると警告が出力され、コピーする事が出来ません。その為、ディレクトリをコピーする「-r」オプションを利用します。

[engineer-club@test]$ls -l
total 8
drwxrwxr-x. 2 engineer-club engineer-club 25 Apr 14 12:22 cpdir
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest2.txt
[engineer-club@test]$cp cpdir cpdir2
cp: omitting directory ‘cpdir’
[engineer-club@test]$
[engineer-club@test]$cp -r cpdir cpdir2
[engineer-club@test]$ls -l
total 8
drwxrwxr-x. 2 engineer-club engineer-club 25 Apr 14 12:22 cpdir
drwxrwxr-x. 2 engineer-club engineer-club 25 Apr 14 12:23 cpdir2
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest2.txt
[engineer-club@test]$

実行の結果、「-r」オプションを利用することで、ディレクトリをコピーする事が出来ました。

2-3.コピー元の日時を継承する

cpコマンドにてコピーしたファイルの日時は、原則としてコピー実行時となります。しかしながら、コピー元のファイルが作成(若しくは更新)された日時を変更したくない場合、「-p」オプションを利用する事でコピー元ファイルの日時を継承する事が出来ます。

[engineer-club@test]$ls -l
total 8
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 13:02 cptest2.txt
[engineer-club@test]$
[engineer-club@test]$cp -p cptest1.txt cptest3.txt
[engineer-club@test]$ls -l
total 12
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 13:02 cptest2.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest3.txt
[engineer-club@test]$

実行の結果、「-p」オプションでコピーすると、cptest3.txtはコピー元となるcptest1.txtの作成(更新)日時を継承している事が分かります。コピー元ファイルの日時を変更しない事で、どの時点で変更が加えられたファイルなのかが残る為、バックアップを取得する際などに有効です。

2-4.上書き確認を行う

コピー先のディレクトリ内に同一のファイル名が存在した場合、cpコマンドはファイルを上書きします。一度上書きされてしまったファイルを元に戻す事は出来ない為、コピー先に同一名称のファイルがないか確認する事が大切です。しかしながら、同一名称ファイルの有無を確認し忘れてしまった場合など、万が一に備え、同一ファイル名がある場合にはインタラクティブに上書き確認を行う「-i」オプションが有効です。

[engineer-club@test]$ls -l
total 4
drwxrwxr-x. 2 engineer-club engineer-club 25 Apr 14 13:16 cpdir
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
[engineer-club@test]$ls -l cpdir/
total 4
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 13:29 cptest1.txt
[engineer-club@test]$cp -i cptest1.txt cpdir/
cp: overwrite ‘cpdir/cptest1.txt’? no
[engineer-club@test]$

実行の結果、cpdir配下に同じ名前のファイル(cptest1.txt)が存在した場合、上書き(overwrite)するか確認メッセージが出力されました。y若しくはyesを入力すれば上書きされ、n若しくはnoを入力すればコピーは中止されます。※同一ファイル名が存在しない場合には、インタラクティブなメッセージは出力されずにコピーされます。


3.コマンドのサンプル

cpコマンドを用いたサンプルをいくつかご紹介します。

①指定した複数のファイルを同時にコピーする

この場合、cp [コピー元ファイル1]  [コピー元ファイル2]  [コピー先]と、対象となるコピー元ファイルを複数指定する事で一度にコピーする事が出来ます。

[engineer-club@test]$ ls -l
total 8
drwxrwxr-x. 2 engineer-club engineer-club 6 Apr 14 13:59 cpdir
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest2.txt
[engineer-club@test]$
[engineer-club@test]$cp cptest1.txt cptest2.txt cpdir/
[engineer-club@test]$ls -l cpdir/
total 8
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 13:59 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 13:59 cptest2.txt
[engineer-club@test]$

実行の結果、cptest1.txtcptest2.txtが同時にcpdir配下へコピーされました。

②ワイルドカードを用いてコピーする

複数ファイルを同時にコピーする場合には、ワイルドカードを用いてコピーする事が出来ます。ワイルドカード「*(アスタリスク)」を用いる事で、前方・後方・部分一致など様々な指定が可能です。

[engineer-club@test]$ls -l
total 8
drwxrwxr-x. 2 engineer-club engineer-club 6 Apr 14 14:06 cpdir
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest2.txt
[engineer-club@test]$cp cptest*.txt cpdir/
[engineer-club@test]$ls -l cpdir/
total 8
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 14:07 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 14:07 cptest2.txt
[engineer-club@test]$

実行の結果、cptest*.txtに該当するファイルがコピーされました。また拡張子が「.txt」であるファイルをコピーする場合には「*.txt」と指定します。

[engineer-club@test]$ls -l
total 8
drwxrwxr-x. 2 engineer-club engineer-club 6 Apr 14 14:10 cpdir
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest2.txt
[engineer-club@test]$cp *.txt cpdir/
[engineer-club@test]$ls -l cpdir/
total 8
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 14:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 14:10 cptest2.txt
[engineer-club@test]$

③コピー先のファイル名に日付を付与する

バックアップファイルを取得する際、バックアップ取得日付を付与してコピーする場合、「date」コマンドの「+%Y%m%d」オプションを利用します。

[engineer-club@test]$ls -l
total 8
drwxrwxr-x. 2 engineer-club engineer-club 44 Apr 14 14:10 cpdir
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest2.txt
[engineer-club@test]$cp cptest1.txt cptest1_date "+%Y%m%d".txt
[engineer-club@test]$ls -l
total 12
drwxrwxr-x. 2 engineer-club engineer-club 44 Apr 14 14:10 cpdir
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 15:48 cptest1_20190414.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest2.txt
[engineer-club@test]$

実行の結果、コピー実施日の日付がファイル名に付与されました。コピー先のファイル名として日付を直接指定しても良いのですが、シェルスクリプトなどに組み込む場合など、動的に日付を付与する時に有効です。

※時刻を付与する場合には、”+%Y%m%d_%H%M%S”により「日付_時刻」とする事も可能です。

④複数のファイルに複製する

単一のファイルを複数のファイルとしてコピーする場合には、ループ処理と組み合わせる方法が有効です。例えば、ファイル名の末尾に13の連番を付与して3つのファイルとしてコピーする場合には、「for」コマンドのリストへ「seq」コマンドによる「13」の数値を格納し、「cp」コマンドを繰り返すなどの方法があります。

[engineer-club@test]$ls -l
total 12
drwxrwxr-x. 2 engineer-club engineer-club 44 Apr 14 14:10 cpdir
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 15:48 cptest1_20190414.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 12:10 cptest2.txt
[engineer-club@test]$for list in seq 1 3
> do
> cp cptest1.txt cpdir/cptest1_$list.txt
> done
[engineer-club@test]$ls -l cpdir/
total 12
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 16:00 cptest1_1.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 16:00 cptest1_2.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 16:00 cptest1_3.txt
[engineer-club@test]$

実行の結果、forコマンドの$listへ、seqコマンドによって指定された13の数値が格納され、dodoneの処理(cptest1.txtcpdir配下へcptest1_[$listの数値].txtとしてコピーする)を繰り返し、cptest1_1.txtcptest1_3.txtとして3つのファイルへコピーされました。

<一口メモ>

seqコマンドとは、「sequence(シーケンス)」の略であり、引数として指定したn1n2を連番で出力するコマンドとなります。例えば、「seq 1 100」を実行すると、1100までの整数が連番で出力されます。ファイルへ連続する番号を付与する処理や、予め予定射ていた繰り返し回数などを指定する際に有効です。


4.作業ミスを防止する鉄板行動

運用業務などにて作業ミスを防止するには、面倒であっても一つ一つ確認する事が大事です。確認しなければならないポイントは、①バックアップを確実に取得する②変更前はバックアップと差分がない事を確認する③変更後はバックアップとの差分(更新箇所)を確認する、の最低でも3ステップとなります。

①確実なバックアップ

作業開始時の状態を確認し、取得予定のバックアップファイル名が利用されていない事を確認した後に、バックアップの取得および湯得したバックアップファイルの存在を確認します

[engineer-club@test]$ls -l
total 4
drwxrwxr-x. 2 engineer-club engineer-club 6 Apr 14 16:15 old
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 16:14 teppan.txt
[engineer-club@test]$ls -l old/bk_teppan.txt
ls: cannot access old/bk_teppan.txt: No such file or directory
[engineer-club@test]$cp -p teppan.txt old/bk_teppan.txt
[engineer-club@test]$ls -l old/bk_teppan.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 16:14 old/bk_teppan.txt
[engineer-club@test]$

実行の結果、バックアップ(コピー)後のファイルが存在しない事を確認してから、バックアップの取得および実行後の確認を行います。

②変更前の差分確認

バックアップ元のファイルと、バックアップ先ファイルの内容を比較し、差分がない事を確認します。

[engineer-club@test]$ls -l teppan.txt old/bk_teppan.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 16:14 old/bk_teppan.txt
-rw-rw-r–. 1 engineer-club engineer-club 19 Apr 14 16:14 teppan.txt
[engineer-club@test]$diff teppan.txt old/bk_teppan.txt
[engineer-club@test]$

実行の結果、バックアップ元ファイルとバックアップ先ファイルを表示させ、双方ともに存在していることの確認および、「diff」コマンドによって差分がない事が確認できます。これにより、確実なバックアップが取得された事になります。

尚、作業ミスを起こさない為の操作方法ですが、上記lsコマンドにて対象ファイルを指定した後は、カーソルキーの「↑()」を1回押下して直前のコマンド実行内容(ヒストリ)を表示させます。その後、「Ctrl+a」で文字列の先頭へカーソルを移動し、 「Ctrl+d」で1文字ずつコマンド(ls –l)を削除、そして「diff」を入力する事で、対象となるファイル名を入力する事なく比較する事が出来ます。これは、比較対象ファイルの入力ミスや誤りを防止する対策として有効(作業ミスをなくす鉄板操作)です。

③変更後の差分確認

バックアップ元ファイルを変更した後には、上記同様にカーソルキーの上を押下し、直前の比較コマンドを再度実行します。

[engineer-club@test]$echo “This is test.” >> teppan.txt
[engineer-club@test]$diff teppan.txt old/bk_teppan.txt
2d1
< This is test.
[engineer-club@test]$

実行の結果、バクアップ元(変更対象)ファイルとバックアップ先ファイルでは、変更箇所のみが差分として出力されますので、変更内容及び変更箇所が想定通りのものであるか確認します。

<一口メモ>

diff」コマンドは指定した2つのファイルを比較し、差分を出力するコマンドです。出力情報は、指定したファイルのどちらかを示す「< (若しくは>)」の後に差分内容を出力します。上記の例ではteppan.txtに「This is test.」が差分として存在している事を表しています。

この鉄板行動・鉄板操作は、cpコマンドの他に「mv」コマンドや「rm」コマンドと言った操作系コマンドを用いる際に実施する事で、ケアレスミスなどを確実に防止する事が出来ます。

★Appendix.パーミッションとは

パーミッションとは一部を除き「権限」を意味し、「Permission denied」とは「権限がありません」と言う意味です。Linuxにおける権限は8進数で表され、①オーナー②グループ③その他の3つに区切られます。「ls」コマンドの「-l」オプションで表示される「-rw-r–r–」というのがパーミッションです。

基本的には先頭から3バイトがオーナー(ファイル類の所有者)の権限、次の3バイトが同じグループに属しているユーザーの権限、最後の3バイトがその他ユーザーの権限となります。

つまり「-rw-r–r–」とは、オーナーは読み書きが可能、グループユーザーは読み込みのみ可能、その他ユーザーも読み込みのみ可能となり、8進数では「644(ろくよんよん)」と読みます。

尚、先頭に「d」が付くものはディレクトリを示し、「l」が付くものはリンクとなっています。パーミッションの表記については、下記の表を参照ください。

表記8進数意味
r4読み取り権限
w2書き込み権限
x1実行権限
dディレクトリ
lリンク

1.2.パーミッション表記

例えば、「drwx-r-x-r-x」の様なディレクトリのパーミッションがあったとします(読み方は「755(ななごーごー))

この場合、ディレクトリのオーナーは書き込み権限(w)があるのですが、グループユーザー及びその他ユーザーには書き込み権限(w)がないので、ファイル類をコピーすることは出来ず、「Permission denied」となるのです。

5.最後に

Liux環境では欠かせないファイルやディレクトリ、そして文字列をコピーするcpコマンドをご紹介しました。非常に良く使うコマンドなのですが、実は「エラーを引き起こしやすい」コマンドでもあります。その多くに権限(パーミッション)不足や意図しない上書きなどが挙げられますので、コピー元・先の権限確認やオプションを駆使したミスの防止などを意識する様に心掛けましょう。

私たちは、全てのエンジニアに市場価値を高め自身の望む理想のキャリアを歩んでいただきたいと考えています。もし、今あなたが転職を検討しているのであればこちらの記事をご一読ください。理想のキャリアを実現するためのヒントが見つかるはずです。

『技術力』と『人間力』を高め市場価値の高いエンジニアを目指しませんか?

私たちは「技術力」だけでなく「人間力」の向上をもって遙かに高い水準の成果を出し、関わる全ての人々に感動を与え続ける集団でありたいと考えています。

高い水準で仕事を進めていただくためにも、弊社では次のような環境を用意しています。

  • 定年までIT業界で働くためのスキル(技術力、人間力)が身につく支援
  • 「給与が上がらない」を解消する6ヶ月に1度の明確な人事評価制度
  • 平均残業時間17時間!毎週の稼動確認を徹底しているから実現できる働きやすい環境

現在、株式会社ボールドでは「キャリア採用」のエントリーを受付中です。

まずは以下のボタンより弊社の紹介をご覧いただき、あなたの望むキャリアビジョンをエントリーフォームより詳しくお聞かせください。

コメント