0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

cp, rsync で隠しファイルもコピーしたければ、xxx/* ではなくて xxx/. を使う

Last updated at Posted at 2025-01-14

目的

cp, rsync, mv, rm の挙動を理解する。

結論

ディレクトリの中身を丸ごとコピー・移動する

aaa_parent/aaa_source/ ディレクトリの中身をそのまま、ddd_parent/ddd_dest/にコピーしたい場合、下記のいずれかのコマンドを使用するのがいい。

~/practice$ rm -rf ddd_parent/ddd_dest/ ※ コピー先ディレクトリに余計なファイルがある場合
~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ cp -a aaa_parent/aaa_source/. ddd_parent/ddd_dest/
~/practice$ rm -rf ddd_parent/ddd_dest/ ※ コピー先ディレクトリに余計なファイルがある場合
~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ rsync -a aaa_parent/aaa_source/. ddd_parent/ddd_dest/

aaa_parent/aaa_source/ ディレクトリの中身をそのまま、ddd_parent/ddd_dest/に移動したい場合、下記のコマンドを使用するのがいい。

~/practice$ rm -rf ddd_parent/ddd_dest/
~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ cp -a aaa_parent/aaa_source/. ddd_parent/ddd_dest/
~/practice$ rm -rf aaa_parent/aaa_source/
~/practice$ mkdir -p aaa_parent/aaa_source/ ※ aaa_parent/aaa_source/ ディレクトリを残しておきたい場合

ファイルをコピー・移動する

aaa_parent/aaa_source/.bbb ファイルを、ddd_parent/ddd_dest/.bbb として配置されるようにコピーする。

~/practice$ rm -rf ddd_parent/ddd_dest/.bbb ※ これをしないと ddd_parent/ddd_dest/.bbb フォルダがある場合、ddd_parent/ddd_dest/.bbb/.bbb として配置されてしまう。
~/practice$ mkdir -p ddd_parent/ddd_dest/
# (1) OK
~/practice$ cp aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest/.bbb
# (2) OK
~/practice$ cp aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest/
# (3) 非推奨
# ddd_parent/ddd_dest ディレクトリがなく、ddd_parent ディレクトリのみがある場合、.bbb ファイルが ddd_parent/ddd_dest ファイルとして配置されてしまう。
~/practice$ cp aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest

aaa_parent/aaa_source/.bbb ファイルを、ddd_parent/ddd_dest/.bbb として配置されるように移動する。

~/practice$ rm -rf ddd_parent/ddd_dest/.bbb ※ これをしないと ddd_parent/ddd_dest/.bbb フォルダがある場合、ddd_parent/ddd_dest/.bbb/.bbb として配置されてしまう。
~/practice$ mkdir -p ddd_parent/ddd_dest/
# (1) OK
~/practice$ mv aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest/.bbb
# (2) OK
~/practice$ mv aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest/
# (3) 非推奨
# ddd_parent/ddd_dest ディレクトリがなく、ddd_parent ディレクトリのみがある場合、.bbb ファイルが ddd_parent/ddd_dest ファイルとして配置されてしまう。
~/practice$ mv aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest

検証

cp コマンド

aaa_parent/aaa_source/ ディレクトリの中身をそのまま、ddd_parent/ddd_dest/にコピーしたいとする。
現在のディレクトリ構成は下記である。

~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
└── memo.md

2 directories, 4 files

(方法1) 成功

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ cp -a aaa_parent/aaa_source/. ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       ├── .bbb
│       └── ccc.txt
└── memo.md

4 directories, 6 files

(方法2) 失敗

隠しファイルがコピーされない。

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ cp -a aaa_parent/aaa_source/* ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       └── ccc.txt
└── memo.md

4 directories, 5 files

(方法3)

下記の検証を見てもらうとわかるが、コピー先のディレクトリがあるかどうかで挙動が変わってくる。

(方法3-1) 成功

~/practice$ mkdir -p ddd_parent/
~/practice$ cp -a aaa_parent/aaa_source/ ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       ├── .bbb
│       └── ccc.txt
└── memo.md

4 directories, 6 files

(方法3-2) 失敗

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ cp -a aaa_parent/aaa_source/ ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       └── aaa_source
│           ├── .bbb
│           └── ccc.txt
└── memo.md

5 directories, 6 files

rsync コマンド

目的は cp コマンドの時と同じ。

(方法1) 成功

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ rsync -a aaa_parent/aaa_source/. ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       ├── .bbb
│       └── ccc.txt
└── memo.md

4 directories, 6 files

(方法2) 失敗

隠しファイルがコピーされない。

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ rsync -a aaa_parent/aaa_source/* ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       └── ccc.txt
└── memo.md

4 directories, 5 files

(方法3)

下記の検証を見ると、コピー先のディレクトリの有無は、挙動に関係ないみたい。

(方法3-1) 成功

~/practice$ mkdir -p ddd_parent/
~/practice$ rsync -a aaa_parent/aaa_source/ ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       ├── .bbb
│       └── ccc.txt
└── memo.md

4 directories, 6 files

(方法3-2) 成功

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ rsync -a aaa_parent/aaa_source/ ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       ├── .bbb
│       └── ccc.txt
└── memo.md

4 directories, 6 files

mv コマンド

aaa_parent/aaa_source/ ディレクトリの中身をそのまま、ddd_parent/ddd_dest/に移動したいとする。
aaa_sourceディレクトリは消えてもいいし、残ってもいいとする
現在のディレクトリ構成は下記である。

~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
└── memo.md

2 directories, 4 files

(方法1) 失敗

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ mv aaa_parent/aaa_source/. ddd_parent/ddd_dest/
mv: cannot move 'aaa_parent/aaa_source/.' to 'ddd_parent/ddd_dest/.': Device or resource busy
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
└── memo.md

4 directories, 4 files

(方法2) 失敗

隠しファイルが移動されない。

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ mv aaa_parent/aaa_source/* ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       └── .bbb
├── ddd_parent
│   └── ddd_dest
│       └── ccc.txt
└── memo.md

4 directories, 4 files

(方法3)

(方法3-1) 成功

aaa_sourceディレクトリは消える

~/practice$ mkdir -p ddd_parent/
~/practice$ mv aaa_parent/aaa_source/ ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
├── ddd_parent
│   └── ddd_dest
│       ├── .bbb
│       └── ccc.txt
└── memo.md

3 directories, 4 files

(方法3-2) 失敗

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ mv aaa_parent/aaa_source/ ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
├── ddd_parent
│   └── ddd_dest
│       └── aaa_source
│           ├── .bbb
│           └── ccc.txt
└── memo.md

4 directories, 4 files

(方法4) ディレクトリ構成の結果的には成功だが、エラー出てるので失敗

aaa_sourceディレクトリは残る
エラー終了しているが、目的は達成できている。
'aaa_parent/aaa_source/.' (aaa_sourceディレクトリにとってのカレントディレクトリ) と 'aaa_parent/aaa_source/..' (aaa_sourceディレクトリにとっての親ディレクトリ) の移動は失敗しているが、.bbb の移動には成功している。

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ mv aaa_parent/aaa_source/* aaa_parent/aaa_source/.* ddd_parent/ddd_dest/
mv: cannot move 'aaa_parent/aaa_source/.' to 'ddd_parent/ddd_dest/.': Device or resource busy
mv: cannot move 'aaa_parent/aaa_source/..' to 'ddd_parent/ddd_dest/..': Device or resource busy
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
├── ddd_parent
│   └── ddd_dest
│       ├── .bbb
│       └── ccc.txt
└── memo.md

4 directories, 4 files

(方法5) 成功

aaa_sourceディレクトリは消える

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ cp -a aaa_parent/aaa_source/. ddd_parent/ddd_dest/
~/practice$ rm -rf aaa_parent/aaa_source/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
├── ddd_parent
│   └── ddd_dest
│       ├── .bbb
│       └── ccc.txt
└── memo.md

3 directories, 4 files

rm コマンド

aaa_parent/aaa_source/ ディレクトリの中身を削除したい。
aaa_parent/aaa_source/ ディレクトリは残ってもいいし、消えてもいいとする。
現在のディレクトリ構成は下記である。

~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
└── memo.md

2 directories, 4 files

(方法1) 成功

aaa_sourceディレクトリは消える

~/practice$ rm -rf aaa_parent/aaa_source/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
└── memo.md

1 directory, 2 files

(方法2) 失敗

隠しファイルが削除されない。

~/practice$ rm -rf aaa_parent/aaa_source/*
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       └── .bbb
└── memo.md

2 directories, 3 files

(方法3) 失敗

~/practice$ rm -rf aaa_parent/aaa_source/.
rm: refusing to remove '.' or '..' directory: skipping 'aaa_parent/aaa_source/.' 
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
└── memo.md

2 directories, 4 files

mv コマンドでファイルを移動する。

aaa_parent/aaa_source/.bbbddd_parent/ddd_dest の中に移動したい。
現在のディレクトリ構成は下記。

~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
└── memo.md

2 directories, 4 files

(方法1-1) 成功

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ mv aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest/
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       └── .bbb
└── memo.md

4 directories, 4 files

(方法1-2) 成功

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ mv aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       └── .bbb
└── memo.md

4 directories, 4 file

(方法1-3) 成功

~/practice$ mkdir -p ddd_parent/ddd_dest/
~/practice$ mv aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest/.bbb
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
│       └── .bbb
└── memo.md

4 directories, 4 files

(方法2-1) 失敗

~/practice$ mkdir -p ddd_parent/
~/practice$ mv aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest/
mv: cannot move 'aaa_parent/aaa_source/.bbb' to 'ddd_parent/ddd_dest/': Not a directory
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
└── memo.md

3 directories, 4 files

(方法2-2) 失敗

ddd_destはディレクトリではなくてファイルであり、.bbbファイルの名前が変更しただけである。

~/practice$ mkdir -p ddd_parent/
~/practice$ mv aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       └── ccc.txt
├── ddd_parent
│   └── ddd_dest
└── memo.md

3 directories, 4 files

(方法2-3) 失敗

~/practice$ mkdir -p ddd_parent/
~/practice$ mv aaa_parent/aaa_source/.bbb ddd_parent/ddd_dest/.bbb
mv: cannot move 'aaa_parent/aaa_source/.bbb' to 'ddd_parent/ddd_dest/.bbb': No such file or directory
~/practice$ tree -a -L 4 -I ".git"
.
├── README.md
├── aaa_parent
│   └── aaa_source
│       ├── .bbb
│       └── ccc.txt
├── ddd_parent
└── memo.md

3 directories, 4 files
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?