cp -RTでディレクトリの中身だけ別のディレクトリにコピーする
先日、Railsチュートリアル用の環境をDockerで整えてみたが、そのときに詰まったのが「ゲスト環境で rails new
して生成されたファイルを、ホスト環境との共有ボリュームにコピーする」ところ。ゲスト環境で /myapp
(←自分のアプリ名)配下に生成されたファイルやディレクトリを、そのまま/app
に移す必要があったのだが、普通に cp
コマンドを使うだけではうまくいかなかった。
簡略化のため、以下のようなシンプルな例で考えてみる。 /src
配下のファイルやディレクトリを、すべて /dest
以下にコピーしたい。
tree -a
.
├── dest
└── src
├── .hidden
├── fuga.rb
└── hoge
└── hoge.rb
cp -R src dest
だと、 src
というディレクトリごとコピーされて、階層がひとつ深くなってしまう。
cp -R src dest tree -a . ├── dest │ └── src │ ├── .hidden │ ├── fuga.rb │ └── hoge │ └── hoge.rb └── src ├── .hidden ├── fuga.rb └── hoge └── hoge.rb
cp -R src/* dest
は一見うまくいきそうだが、ドットファイル(この場合は .hidden
)がコピーされない。
cp -R src/* dest tree -a . ├── dest │ ├── fuga.rb │ └── hoge │ └── hoge.rb └── src ├── .hidden ├── fuga.rb └── hoge └── hoge.rb
このような場合は、cpコマンドのT
オプションを使う。通常のcpコマンドは、 cp src dest
のような形式のとき、destがディレクトリなら cp src dest/src
と同じ動作をする。しかしTオプションがある場合、最後の引数がディレクトリでもこのような特別扱いがなされないため、 cp -RT src dest
とすれば、srcディレクトリの中身がdestディレクトリ内にコピーされる。
cp -RT src dest tree -a . ├── dest │ ├── .hidden │ ├── fuga.rb │ └── hoge │ └── hoge.rb └── src ├── .hidden ├── fuga.rb └── hoge └── hoge.rb
これでドットファイルまで含めてコピーできた。
なお、Macにデフォルトで入っているcpコマンドはBSD版のため、 -T
オプションがない。Macで使いたい場合は、 brew install coreutils
でGNU版のcpコマンドをインストールする必要がある。
追記(1/12)
cp -r src/. dest/
でもドットファイルごとコピーできた。
また、docker-compose.ymlのvolumeに適切な指定をしていれば必要なファイルを自動で共有させられるので、ホスト/ゲスト間のやり取りはcpで頑張らない方が良さそう。
指摘いただいた@budougumi0617さん、ありがとうございます。