スポンサーリンク

【Ubuntu】ファイルやディレクトリをコピーする方法(cp)

Ubuntuでファイルやディレクトリをコピーする方法です。

cpでファイルやディレクトリをコピー

「cp」コマンドを使用することでファイルやディレクトリをコピーすることが出来ます。

ファイルをコピー

ファイルのコピーは以下の方法で行うことが出来ます。

cp コピー元 コピー先

「test_01.txt」を「test_02.txt」という名前でコピーする場合は下記の様に「cp」コマンドを実行します。

$ cp test_01.txt test_02.txt

「test_02.txt」がコピーされていることが確認できました。

$ ls -l
total 8
-rw-rw-r-- 1 tamohiko tamohiko 7 Oct 15 09:55 test_01.txt
-rw-rw-r-- 1 tamohiko tamohiko 7 Oct 15 09:57 test_02.txt

コピー先にディレクトリを指定した場合

コピー先にディレクトリを指定すると、指定したディレクトリ内にファイルがコピーされます。

cp コピー元 コピー先ディレクトリ/

コピー先に「dir_01」というディレクトリを指定して、「test_01.txt」ファイルをコピーします。

$ cp test_01.txt dir_01/

「dir_01」ディレクトリ内を確認すると、「test_01.txt」ファイルがコピーされていることが確認できます。

$ ls -l dir_01/
total 4
-rw-rw-r-- 1 tamohiko tamohiko 7 Oct 15 10:00 test_01.txt

ディレクトリをコピー

ディレクトリをコピーする場合は「-r」オプションを使用します。(-R, --recursiveでも可)

cp -r コピー元 コピー先

実際に「dir_01」というディレクトリを「dir_02」という名前でコピーしてみます。

$ cp -r dir_01/ dir_02/

無事ディレクトリの中身を含めてコピーできました。

$ ls -R dir_*
dir_01:
test_01.txt

dir_02:
test_01.txt

「-r」を使わずディレクトリをコピーした場合

「-r」オプションを使用せずにディレクトリのコピーを行うと、「-r」オプションが指定されていないというメッセージが表示されてコピーを行うことは出来ません。

$ cp dir_01/ dir_02/
cp: -r not specified; omitting directory 'dir_01/'

コピー元の情報(所有者、タイムスタンプ、パーミッション)をそのままコピーする

「-p」オプションを使用すると、所有者、タイムスタンプ、パーミッションなどの情報をそのままコピーすることが出来ます。

$ cp -p test.txt test_00.txt
$ ls -l test*.txt 
-rw-rw-r-- 1 tamohiko tamohiko 10 Oct 14 22:47 test.txt
-rw-rw-r-- 1 tamohiko tamohiko 10 Oct 14 22:47 test_00.txt

私は「cp」を行う時、特に理由がない場合は「-p」オプションつけています。

「-p」オプションを使用しなかった場合

コピー先のタイムスタンプが変更されてしまいます。

$ cp test.txt test_00.txt
$ ls -l test*.txt 
-rw-rw-r-- 1 tamohiko tamohiko 10 Oct 14 22:47 test.txt
-rw-rw-r-- 1 tamohiko tamohiko 10 Oct 18 18:00 test_00.txt
別ユーザが「cp」した場合

コピーしたユーザが所有者となり、タイムスタンプがコピーした時間に変更され、パーミッションはそのユーザに設定されている「umask」の設定に変更されます。

「tamohiko」が作成したファイルを「tamo」というユーザでコピーすると所有者がコピーを行った「tamo」に変更されます。

$ whoami
tamo
$ cp /home/tamohiko/test.txt test_01.txt
$ ls -l test_01.txt 
-rw-rw-r-- 1 tamo tamo 10 10月 18 18:05 test_01.txt

「root」ユーザでコピーを行うと、「umask」の設定が一般ユーザと異なっているためパーミッションも変更されてしまっています。

# whoami
root
# cp test.txt test_01.txt
# ls -l test_01.txt 
-rw-r--r-- 1 root root 10 10月 21 12:41 test_01.txt

複数ファイルのコピー

コピー先にディレクトリを指定する場合、コピー元を複数指定すると一度に複数のファイルをディレクトリ内にコピーすることが出来ます。

cp コピー元1 コピー元2 コピー元3 コピー先ディレクトリ/

「test_01.txt」「test_02.txt」「test_03.txt」というファイルを「dir_01」ディレクトリにコピーしてみます。

$ cp -p test_01.txt test_02.txt test_03.txt dir_01/

「dir_01」ディレクトリの中に指定した3つのファイルがコピーされています。

$ ls dir_01/
test_01.txt  test_02.txt  test_03.txt

コピー先がディレクトリではない場合

コピー先がディレクトリではない場合は、コピー先がディレクトリではないとメッセージが表示されてコピーすることが出来ません。

$ cp test_01.txt test_02.txt test_03.txt        
cp: target 'test_03.txt': Not a directory

オプションの説明

他にもまだありますが、今回は「cp」を使う際に普段使用しそうなオプションを抜粋して説明します。

オプション 説明
-v コピーの実行状況を表示
-b コピー先に同じ名前のファイルがすでに存在していた場合バックアップを作成
-S 接尾辞 コピー先に同じ名前のファイルがすでに存在していた場合作成されるバックアップの接尾辞を指定
-i, --interactive コピー先に同じ名前のファイルがすでに存在していた場合に確認を行う
-n, --no-clobber (--update=none ※Ubuntu24.04) コピー先に同じ名前のファイルがすでに存在していた場合コピーを行わない
-f, --force 強制的にコピーを行う
「-i」と同時に使用した場合は「-i」が優先される
Ubuntu24.04では --update=all も使用できる 強制的にコピーを行う
「-i」と同時に使用した場合は「--update=all」が優先される

使用例

「cp」コマンドを実際に実行しながら、オプションの動作について説明していきます。

どのようにコピーが行われているかを表示させるために「-v」オプションも同時に指定していますが、「コピーの実行内容を表示させる必要がない場合は特に指定する必要はありません。

-v コピーの実行内容を表示

「-v」オプションを使用すると、コピーをどの様に行ったかの情報を表示させることが出来ます。

下記の場合、「test.txt」が「test_00.txt」にコピーされたことが表示されています。

$ cp -v test.txt test_00.txt
'test.txt' -> 'test_00.txt'

-b バックアップを作成

コピー先に同じ名前のファイルが存在していた場合、既存ファイルのバックアップを作成してくれます。

下記の場合バックアップファイルは「test_00.txt~」という名前で作成されています。

$ cp -vb test.txt test_00.txt
'test.txt' -> 'test_00.txt' (backup: 'test_00.txt~')

このときバックアップされたファイルのバックアップは作成されないので注意が必要です。

「test_00.txt~」がバックアップとして作成された状態で、再度「cp -vb test.txt test_00.txt」を実行した場合、「test_00.txt~」は新しく作成されたバックアップファイルで上書きされてしまいます。

-S 接尾辞 接尾辞を指定してバックアップを作成

「-S」オプションを使用すると、コピー先に同じ名前のファイルが存在していた場合に作成されるバックアップファイルの接尾辞を設定することが出来ます。

接尾辞に「_BK」を指定した場合は、下記のように「test_01.txt_BK」という名前でバックアップを作成してくれます。

$ cp -vS _BK test.txt test_00.txt 
'test.txt' -> 'test_00.txt' (backup: 'test_00.txt_BK')

-i, --interactive コピーの確認メッセージを表示

コピー先に同じ名前のファイルが存在していた場合、ファイルを上書きするか確認するメッセージを表示します。

上書きする場合は「y」を入力し「Enter」キーを押下します。

$ cp -vi test.txt test_00.txt
cp: overwrite 'test_00.txt'? y
'test.txt' -> 'test_00.txt'

上書きしない場合は、 そのまま「Enter」キーを押下します。

$ cp -vi test.txt test_00.txt
cp: overwrite 'test_00.txt'? 

-n, --no-clobber 上書きコピーを行わない(Ubuntu24.04では --update=none)

「-n」オプションを使用すると、コピー先に同名のファイルが存在していた場合はコピーを行いません。

$ cp -vn test.txt test_00.txt 

Ubuntu24.04では--update=none

Ubuntu24.04の「cp」コマンド(GNU coreutils)のバージョンは9.4になっています。

$ cat /etc/issue
Ubuntu 24.04.1 LTS \n \l
$ cp --version
cp (GNU coreutils) 9.4
Copyright (C) 2023 Free Software Foundation, Inc.
##### 以下省略 #####

このバージョンの「cp」コマンドは「-n」や「--no-clobber」オプションを使用すると、既存ファイルへ上書きは行われませんが、「--update=none」を使用してくださいとメッセージが表示されます。

$ cp -vn test.txt test_00.txt 
cp: warning: behavior of -n is non-portable and may change in future; use --update=none instead

「--update=none」オプションを使用するとメッセージは表示されませんし、既存ファイルへ上書きも行われません。

$ cp -v --update=none test.txt test_01.txt 

ちなみに、「--update=none」は「cp」(GNU coreutils)のバージョン9.3から使用できるようになっています。

** New features

cp and mv now support --update=none to always skip existing files
in the destination, while not affecting the exit status.
This is equivalent to the --no-clobber behavior from before v9.2.

引用元:https://savannah.gnu.org/news/?id=10350

-f, --force強制的にコピーを行う

「-f」オプションを使用することで強制的にコピーを行うことが出来ます。

$ ls test*.txt
test.txt  test_00.txt
$ cp -vf test.txt test_00.txt 
'test.txt' -> 'test_00.txt'

「-i」と「-f」では「-i」が優先される

「-i」(上書きの確認メッセージ表示)と「-f」を同時に使用すると「-i」の方が優先されて有効になります。

$ cp -i -f test.txt test_00.txt 
cp: overwrite 'test_00.txt'? 

Ubuntu24.04の場合 「--update=all」でも強制的にコピーを行う

Ubuntu24.04の場合「--update=all」というオプションも使用できるのですが、こちらの場合は「-i」オプションと同時に使用すると「--update=all」のほうが優先されて上書き確認のメッセージを表示させずに強制的にコピーを行うことが出来ます。

$ cp -vi --update=all test.txt test_00.txt 
'test.txt' -> 'test_00.txt'

「--update=all」というオプションはcp (GNU coreutils) のバージョンが9から使用できるようなったオプションです。

間違って上書きコピーを行わないようにする方法

間違って既存のファイルに上書きコピーしないようにするためには、常に「-i」オプションを使用すればよいのですが、手動で指定する場合はついつい忘れてしまうというリスクがあります。

ですので、aliseとして「cp」コマンドを実行すると「cp -i」が実行されるように設定することで「-i」オプションの指定漏れを防ぐことが出来ます。

aliasの設定方法

「alias」を設定する方法色々ありますが、今回はユーザのホームディレクトリに「.bash_aliases」を作成して設定する方法を紹介します。

$ vi ~/.bash_aliases 

設定したいaliasを下記のように記述します。

alias cp='cp -i'

設定反映

「~/.bash_aliases」は「~/.bashrc」から読み込まれているので、「source」コマンドで「~/.bashrc」を読み込むことで設定を反映させることが出来ます。

$ source ~/.bashrc
「~/.bashrc」で「~/.bash_aliases」を読み込む設定

「~/.bashrc」内の下記部分にある設定で「~/.bash_aliases」を読み込んでいます。

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

設定確認

「alias」コマンドを実行すると現在設定されている「alias」が表示されるので、設定した「alias」が表示されているか確認してください。

$ alias | grep cp
alias cp='cp -i'

「alias」が設定されていることが確認できたら、実際に「cp」コマンドを実行して「-i」オプションが有効となっていることを確認してみてください。

$ cp test.txt test_00.txt 
cp: overwrite 'test_00.txt'?

「\」を使うとaliasを一時的に無効化出来ます

「cp」の前に「\」をつけると、設定されている「alias」を一時的に無効化出来ます。

実際に「\」をつけて「cp」コマンドを実行すると、「alias」の設定が無効化されているので上書きの確認メッセージが表示されなくなっています。

$ \cp -v test.txt test_00.txt 
'test.txt' -> 'test_00.txt'

コメント

タイトルとURLをコピーしました