Linuxのcpコマンドとは?ファイルやディレクトリを複製するcpコマンドの使い方
Windows環境でもLinux環境でも、ファイルやディレクトリを複製するコマンドは「cp」コマンドとなります。コピー(copy)の略なので覚えやすいですね。今回は実際の業務で多く用いられる「cp」コマンドの解説と、作業ミスをなくす複製の方法などをご紹介します。また、最後にパーミッションについても触れておりますので、この機会にパーミッションも理解してみましょう。
目次
1.cpコマンドとは
ファイルやディレクトリを複製(コピー)するコマンドです。編集対象ファイルのバックアップ取得や、ソースファイルを複製して利用するなど、多くの業務で利用します。
1-1.コマンドの使い方
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」としてコピーします。
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.txtがcptest2.txtとしてコピーされました。
②指定したディレクトリへコピーする
同様にcptest1.txtを「cpdir」配下にコピーします。この場合、同じファイル名でコピーする事も可能ですが、混乱を招く恐れがありますので、基本的には別名で保存するようにしましょう。ここではcptes3.txtとしてコピーします。
[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.txtがcpdir配下にcptest3.txtとしてコピーされました。
2-2.ディレクトリをコピーする
ディレクトリ「cpdir」を「cpdir2」としてコピーしてみますが、「cpdir」はディレクトリであると警告が出力され、コピーする事が出来ません。その為、ディレクトリをコピーする「-r」オプションを利用します。
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」オプションを利用する事でコピー元ファイルの日時を継承する事が出来ます。
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」オプションが有効です。
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.txtとcptest2.txtが同時にcpdir配下へコピーされました。
②ワイルドカードを用いてコピーする
複数ファイルを同時にコピーする場合には、ワイルドカードを用いてコピーする事が出来ます。ワイルドカード「*(アスタリスク)」を用いる事で、前方・後方・部分一致など様々な指定が可能です。
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」オプションを利用します。
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”により「日付_時刻」とする事も可能です。
④複数のファイルに複製する
単一のファイルを複数のファイルとしてコピーする場合には、ループ処理と組み合わせる方法が有効です。例えば、ファイル名の末尾に1~3の連番を付与して3つのファイルとしてコピーする場合には、「for」コマンドのリストへ「seq」コマンドによる「1~3」の数値を格納し、「cp」コマンドを繰り返すなどの方法があります。
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コマンドによって指定された1~3の数値が格納され、do~doneの処理(cptest1.txtをcpdir配下へcptest1_[$listの数値].txtとしてコピーする)を繰り返し、cptest1_1.txt~cptest1_3.txtとして3つのファイルへコピーされました。
<一口メモ>
seqコマンドとは、「sequence(シーケンス)」の略であり、引数として指定したn1~n2を連番で出力するコマンドとなります。例えば、「seq 1 100」を実行すると、1~100までの整数が連番で出力されます。ファイルへ連続する番号を付与する処理や、予め予定射ていた繰り返し回数などを指定する際に有効です。
4.作業ミスを防止する鉄板行動
運用業務などにて作業ミスを防止するには、面倒であっても一つ一つ確認する事が大事です。確認しなければならないポイントは、①バックアップを確実に取得する②変更前はバックアップと差分がない事を確認する③変更後はバックアップとの差分(更新箇所)を確認する、の最低でも3ステップとなります。
①確実なバックアップ
作業開始時の状態を確認し、取得予定のバックアップファイル名が利用されていない事を確認した後に、バックアップの取得および湯得したバックアップファイルの存在を確認します
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]$
実行の結果、バックアップ(コピー)後のファイルが存在しない事を確認してから、バックアップの取得および実行後の確認を行います。
②変更前の差分確認
バックアップ元のファイルと、バックアップ先ファイルの内容を比較し、差分がない事を確認します。
-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]$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進数 | 意味 |
r | 4 | 読み取り権限 |
w | 2 | 書き込み権限 |
x | 1 | 実行権限 |
d | – | ディレクトリ |
l | – | リンク |
表1.2.パーミッション表記
例えば、「drwx-r-x-r-x」の様なディレクトリのパーミッションがあったとします(読み方は「755(ななごーごー)」)。
この場合、ディレクトリのオーナーは書き込み権限(w)があるのですが、グループユーザー及びその他ユーザーには書き込み権限(w)がないので、ファイル類をコピーすることは出来ず、「Permission denied」となるのです。
5.最後に
Liux環境では欠かせないファイルやディレクトリ、そして文字列をコピーするcpコマンドをご紹介しました。非常に良く使うコマンドなのですが、実は「エラーを引き起こしやすい」コマンドでもあります。その多くに権限(パーミッション)不足や意図しない上書きなどが挙げられますので、コピー元・先の権限確認やオプションを駆使したミスの防止などを意識する様に心掛けましょう。
コメント