アプリ版:「スタンプのみでお礼する」機能のリリースについて

/src/ディレクトリにあるすべてのファイルやサブディレクトリを/dest/ディレクトリにコピーしたいと思っています。
ただ、次のコマンドでは/src/.dotfileといったドットファイルはコピーされません。
$ cp -Rf /src/* /dest/

このようなドットファイルも含めてすべてのファイル、サブディレクトリをコピーするにはどのようにするのがよいのでしょうか?

次のような方法が思い浮かびましたが、もっとシンプル or スマートな方法がありましたら教えてください。
(a)シェルオプションのdotglobを一時的にONにしてから、上記cpコマンドを実行する。
(b)/src/直下のドットファイルだけ別途指定する。
$ cp -Rf /src/{*,.[^.]*} /dest/

A 回答 (5件)

cp -Rf /src/* /src/.* /dest/



だと/src/. や /src/.. も含んでしまうのでダメでしょうね。
shopt -s dotglob
してからやる方が良いと思います。
またはtarを使うか。
    • good
    • 0
この回答へのお礼

lowrider_2005さん
回答ありがとうございます。

質問してから色々と考え試してみましたが、仰るとおりdotglobを一時的にONにするのが一番シンプルで混乱がないという結論に導かれていきました :)

確かにtarでやる方法もありますね。
でもdotglobが簡単ですね。

お礼日時:2014/10/29 13:55

てゆ~か、



$ cp -Rf /src /dest

ってやったら、/srcがディレクトリだから、中身が丸っと全部コピーされないか?
    • good
    • 1
この回答へのお礼

chie65535さん
回答ありがとうございます。

これだと駄目ですね。

お礼日時:2014/10/29 14:08

bashとかだと、dotglobしても、*を展開すると . と .. が入ってきちゃうから、dotglobでも駄目な場合も。



手っ取り早いのは
$ cp -Rf /src/* /src/.[!.]* /src/..?* /dest/
かなあ?

..doubledotfile

っていうファイルが無いなら
$ cp -Rf /src/* /src/.[!.]* /dest/
でも可かな?

ともかく「echoで試してから」で。
    • good
    • 0
この回答へのお礼

chie65535さん
回答ありがとうございます。

> bashとかだと、dotglobしても、*を展開すると . と .. が入ってきちゃうから、dotglobでも駄目な場合も。
dotglobしても echo .* の場合 . や .. が表示されますが、そもそもdotglobするのは .* とかしたくないからするのであってdotglobがONの場合の echo * では . や .. は含まれません。
dotglobが駄目なケースとは具体的にはどのような場合でしょうか?

回答を拝見していてchie65535さん自身が混乱されているように見えることからも、やはり dotglob を使うのがシンプルでわかりやすくていいのかなと正直思いました。
ごめんなさい :)

Linuxでのドットファイルや名前に空白が入るファイルの扱いは、私が慣れていないだけかもしれませんが、結構気を使いますね。

お礼日時:2014/10/29 14:25

因みに。



/src/ディレクトリに、a,b,c,d,e,f,g,.a,.b,.c,.h,.i,.jの12個のファイルがあった場合

$ cp -Rf /src/* /dest/

ってやると、*のワイルドカードに引っ掛かるのはa,b,c,d,e,f,gなので、シェルが「/src/*」を「/src/a /src/b /src/c /src/d /src/e /src/f /src/g」に展開し、ファイルを1つ1つ指定したのと同じ状態にしてから、cpを実行する。

つまり

$ cp -Rf /src/a /src/b /src/c /src/d /src/e /src/f /src/g /dest/

が実行される。

cpは、引数が3つ以上指定された場合は「1番目から、最後の引数の1つ前まで」のファイル群を「最後の引数に指定されたディレクトリにコピーする」と言う仕様になっている。

なので

$ cp -Rf /src/* /src/.* /dest/

ってやると、*のワイルドカードに引っ掛かるのはa,b,c,d,e,f,gの6つ、.*のワイルドカードに引っ掛かるのは.a,.b,.c,.h,.i,.jの6つなので、シェルが「/src/* /src/.*」を「/src/a /src/b /src/c /src/d /src/e /src/f /src/g /src/.a /src/.b /src/.c /src/.h /src/.i /src/.j」に展開し、ファイルを1つ1つ指定したのと同じ状態にしてから、cpを実行する。

つまり

$ cp -Rf /src/a /src/b /src/c /src/d /src/e /src/f /src/g /src/.a /src/.b /src/.c /src/.h /src/.i /src/.j /dest/

が実行され、すべてのファイルがコピーされる。

以下の2つの事を覚えておいて欲しい。

・cpのソースファイルの指定は、複数のファイルを列挙しても良い

・ワイルドカードの展開はシェルがやっている。実行するコマンドがやっているのではない

なお「ワイルドカードの展開結果が正しいかどうかを確認する場合」は

echo /src/* /src/.*

を実行してみると良い(特に「.」と「..」がどうなるか不安な場合に)
    • good
    • 0
この回答へのお礼

chie65535さん
ワイルドカードの解説ありがとうございます。

最近シェルを本格的に(?)勉強し始めたのでよい復習になりました。
ちなみに find . -name '*.txt' の場合の * はシェルではなく、findコマンド自身が展開するというのは最近知りました ^^;

お礼日時:2014/10/29 14:04

$ cp -Rf /src/* /src/.* /dest/


では駄目なの?
    • good
    • 0
この回答へのお礼

chie65535さん
回答ありがとうございます。

No.2でlowrider_2005さんが仰っていますが、/src/.. が含まれてしまうので駄目なんですよね。

お礼日時:2014/10/29 13:50

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!