試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

cpコマンドの引数について

(2019/4/10)本記事は「ファイルやディレクトリのコピーを行うcpコマンドの引数」へ移動した。

以下、以前の内容となる。

基本コマンド集coreutilsの中に含まれるcpというコマンドはファイルやディレクトリをコピーするが、引数の数や対象の状態・種類によって、その動作は微妙に異なる。

  1. 引数の指定
  2. 引数が2つの場合
    1. 2つ目の引数が「存在するディレクトリ」の場合: 同名で指定ディレクトリにコピー
    2. 2つ目の引数が「存在するファイル」の場合: 既存ファイルに上書きコピー
    3. 2つ目の引数が「存在しない場所」の場合: 名前を付けてコピー
  3. 引数が3つ以上の場合: ディレクトリの中にコピー
  4. ディレクトリのコピー

引数の指定

引数は2つ以上必要で、全てファイルやディレクトリの場所を示す。絶対パス指定でも相対パス指定でも可。
最初の引数はコピーしたいファイルやディレクトを指定する。

引数が2つの場合

2つ目の引数が「存在するディレクトリ」の場合: 同名で指定ディレクトリにコピー
よく使われる形で、2つ目の引数に既存のディレクトリが指定されると、1つ目の引数で指定したファイルを(同じ名前で)指定したディレクトリの中にコピーする。
もし同名のファイルが指定ディレクトリにあれば、-iオプション指定時に上書き確認が行われる。

(ディレクトリを2つ作成)
$ mkdir dir1 dir2
(適当な内容のファイルa.txtをdir1に作成)
$ echo "aaa" > dir1/a.txt
(内容の確認)
$ cat dir1/a.txt 
aaa
(dir1/a.txtをdir2の中にコピー)
$ cp dir1/a.txt dir2/
(コピーされたことを確認)
$ cat dir2/a.txt
aaa
(再びコピーすると上書きの確認が行われる)
$ cp -i dir1/a.txt dir2/
cp: `dir2/a.txt' を上書きしてもよろしいですか(yes/no)? y
(後始末)
$ rm dir1/ dir2/ -fr

2つ目の引数が「存在するファイル」の場合: 既存ファイルに上書きコピー
2つ目に指定した引数が既に存在するファイルの場合、そのコピー先の場所のファイルが最初の引数のファイルの内容で上書きされる。

(適当な内容のファイルa.txtとb.txtを作成)
$ echo "aaa" > a.txt
$ echo "bbb" > b.txt
(内容の確認)
$ cat a.txt 
aaa
$ cat b.txt 
bbb
(a.txtの内容をファイルb.txtに上書き)
$ cp -i a.txt b.txt
cp: `b.txt' を上書きしてもよろしいですか(yes/no)? y
(上書きされたことを確認)
$ cat b.txt
aaa
(後始末)
$ rm a.txt b.txt -f

2つ目の引数が「存在しない場所」の場合: 名前を付けてコピー
2つ目の引数に指定した場所にファイルやディレクトリが存在しない場合、引数に指定した名前・場所のファイルとしてコピーする。

(適当な内容のファイルa.txtを作成)
$ echo "aaa" > a.txt
(内容の確認)
$ cat a.txt 
aaa
(2つ目の引数に指定するファイルb.txtが存在しないことを確認)
$ cat b.txt
cat: b.txt: そのようなファイルやディレクトリはありません
(a.txtの内容をb.txtという名前でコピー)
$ cp -i a.txt b.txt
(コピーされたことを確認)
$ cat b.txt
aaa
(後始末)
$ rm a.txt b.txt -f

引数が3つ以上の場合: ディレクトリの中にコピー

引数が3つ以上ある場合、最後の引数がディレクトリとみなされ、その1つ前までの引数に指定したファイル群を全てそのディレクトリにコピーする。
もし、最後の引数に指定したものがディレクトリでない場合にはエラーとなる。

(ディレクトリを2つ作成)
$ mkdir dir1 dir2
(適当な内容のファイルa.txt,b.txt,c.txtをdir1に作成)
$ echo "aaa" > dir1/a.txt
$ echo "bbb" > dir1/b.txt
$ echo "ccc" > dir1/c.txt
(内容の確認)
$ cat dir1/a.txt 
aaa
$ cat dir1/b.txt 
bbb
$ cat dir1/c.txt 
ccc
(dir1/a.txt,dir1/b.txt,dir1/c.txtを全てdir2の中にコピー)
$ cp -i dir1/a.txt dir1/b.txt dir1/c.txt dir2/
(コピーされたことを確認)
$ cat dir2/a.txt 
aaa
$ cat dir2/b.txt 
bbb
$ cat dir2/c.txt 
ccc
(適当な内容のファイルtest.txtを作成)
$ echo "test" > test.txt
(最後の引数をディレクトリ以外にするとエラーになる)
$ cp -i dir1/a.txt dir1/b.txt dir1/c.txt test
cp: target `test' is not a directory
(後始末)
$ rm dir1/ dir2/ -fr

ディレクトリのコピー

ディレクトリの中身を含めたコピーには-rもしくは-Rオプションを使用する。*1あるいは、コピー元の属性も保持するための-aオプションを付ける。*2

(ディレクトリの作成)
$ mkdir dir1
(適当な内容のファイルa.txtをdir1の中に作成)
$ echo "aaa" > dir1/a.txt
(そのままコピーしようとすると失敗)
$ cp dir1 newdir
cp: omitting directory `dir1'
(ディレクトリをコピー)
$ cp -R dir1 newdir
(コピーされたことを確認)
$ cat newdir/a.txt 
aaa
(後始末)
$ rm dir1/ newdir/ -fr

(2015/1/14)manページのリンク先を修正

関連URL:

使用したバージョン:

*1:コピーしたいものがファイルもしくはディレクトリの場合は違いはない

*2:-a-dpRと等価