cpは。(ドット)または..(ドットドット)はソースディレクトリです


15

この回答は、隠しファイルを含むすべてのファイルsrcをディレクトリからディレクトリにコピーできることを示していますdest

mkdir dest
cp -r src/. dest

これが実際に機能する理由についての答えやコメントには説明がなく、これに関するドキュメントも見つけられないようです。

私はいくつかのことを試しました。まず、通常の場合:

$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src dest
$ ls -A dest
dest_file  src

そして、/.最後に:

$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src/. dest
$ ls -A dest
dest_file  .dotfile  src_dir  src_file

したがって、これはと同様に動作しますが*、隠しファイルもコピーします。

$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src/* dest
$ ls -A dest
dest_file  src_dir  src_file

.そして..、適切なハードリンクされているとして、ここで説明したばかりのディレクトリエントリそのもののように、。

この動作はどこから来て、どこに文書化されていますか?


3
誰もドキュメントを見つけることができないという意味ですか?cp参照がどのように明確に説明してcp -R動作します。.そして..ちょうど、他のディレクトリのようなディレクトリです、それらについての魔法や神秘的なものは何もありません。
AlexP

2
@AlexP答えを編集して、わかりやすくしました。全体のポイントはそれで.あり、..他のディレクトリのように振る舞わないでください。
iFreilicht

回答:


27

動作はの文書化されたアルゴリズムの論理的な結果ですcp -RPOSIXのステップ2fを参照してください。

ディレクトリsource_file内のファイルは、ディレクトリdest_fileにコピーされ、ここにリストされた4つのステップ(1から4)をファイルをsource_filesとして使用します

.および..は、それぞれ現在のディレクトリと親ディレクトリのディレクトリです。シェルに関する限り、どちらも特別なものではないので、どちらも展開に関係なく、隠しファイルを含めてディレクトリがコピーされます。*一方、ファイルのリストに展開され、隠しファイルが除外されます。

src/.内の現在のディレクトリでありsrc、それsrc自体です。src/src_dir/..あるsrc_dirのは、再び親ディレクトリ、src。したがって、外部から、ディレクトリのsrc場合srcsrc/.またはsrc/src_dir/..のソースファイルとして指定することcpは同等でありsrc、隠しファイルを含むの内容をコピーします。

指定するポイントは、ディレクトリ(またはディレクトリへのシンボリックリンク)でないsrc/.場合srcは失敗するが、そうでない場合は失敗srcすることです。またsrcsrc自分自身をコピーせずに、コンテンツのみをコピーします。これはドキュメントにも一致します:

ターゲットが存在し、既存のディレクトリに名前を付ける場合、ファイル階層内の各ファイルに対応する宛先パスの名前は、target、ターゲットがスラッシュで終わらない場合は単一のスラッシュ文字、および相対ファイルのパス名の連結です。source_fileを含むディレクトリへ。

だから、cp -R src/. destコピーの内容srcdest/.(ソースファイルがある.中でsrc)、一方cp -R src destの内容をコピーsrcするにはdest/src(ソースファイルがありますsrc)。

これを考えるための別の方法は、コピーと比較することであるsrc/src_dirsrc/.、いうより比較するsrc/.src。前の場合と.同じようsrc_dirに動作します。


ただし、同じようには動作しません。指定srcにディレクトリをコピーしますdestsrc/.内容をコピーします。私は質問でそれを明確にしようとします。
iFreilicht

そこで、私はそれがあなたの根底にある質問に答えると思います。
スティーブンキット

1
@StéphaneOPは、コピーsrc/.src/*(注ではなく src/.*)を比較します。src/*無視にそれらをグロブ場合...隠されたファイルが含まれていません
スティーブン・キット

1
うーん、「source_fileを含むディレクトリ」。まあ、明らかにsrc含まれsrc/.ていますが、それはディレクトリの含まれるディレクトリがディレクトリの命名方法に依存することを意味します。もちろん、ある.意味でリンクが存在するということは、すべてのディレクトリが自分自身を含むことを意味しますが、それはすべてにとって直感的ではないかもしれません。代わりに、この動作の一つにも「ディレクトリを含むディレクトリがあることを前提としたくなるかもしれませんfoo」によって決定されるであろうfoo/..、その場合には、それは問題で、我々はを参照している場合ではないでしょうfoofoo/.:結果の入っているディレクトリは同じになります。
ilkkachu

1
どちらの区別ということであるfoofoo/.少し微妙なようだが、私は気にしない、私もそれが少し面白い見つけます。
イルッカチュ

1

実行するとcp -R src/foo dest、取得しdest/fooます。そのため、ディレクトリdest/fooが存在しない場合は、ディレクトリcpを作成し、次にの内容をコピーsrc/foodest/fooます。

を実行するとcp -R src/. destcpdest/.存在することがわかり、src/.to の内容をコピーするだけdest/.です。

.from という名前のディレクトリをコピーし、srcその内容を既存のディレクトリとマージすると考えるdest/.と、意味があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.