web-dev-qa-db-ja.com

cp -R foo /とcp-R foo / *の違いは何ですか

コマンドcp -R foo/*を使用するときはいつでも、.envまたはおそらく.gitignoreのようなファイルを除くすべてをコピーすることに気づきました。

解決策は、ディレクトリ全体を処理するためにcp -R foo/を使用することですが、これによって、*文字を使用する動作がまだ理解されていないという事実は変わりません。

*文字が.envのようなファイルをキャッチしないのはなぜですか?

OSはDebianです

  • cp -R foo/foo/の下のすべてを再帰的にコピーします
  • cp -R foo/*は、foo/*に一致するすべてのファイルとディレクトリを再帰的にコピーします。また、デフォルトでは、ドット付きの名前は含まれていません(ls *もそれらをリストしません)。これは説明されています ここ (および先頭のドットに関するその他の小さな詳細)。

先頭にドットが付いたファイルの処理に加えて、別の違いは、cp -R foo/*foo/内の個々のファイルとディレクトリをターゲットディレクトリにコピーするのに対し、cp -R foo/foo/のコピーを作成することです。ターゲットディレクトリ内(つまり、もう1つのディレクトリレベルを取得します)。

5
xenoid

デフォルトでは、bashのグロブには.で始まるファイル名が含まれていません。したがって、*を指定すると、「.」で始まるファイルなしで再帰的にコピーするように求められます。 *を指定しない場合、「.」ファイルを含むすべてがコピーされます。

3
Vishal Shinde

あなたが持っている他の答えに加えて、foo/foo/*が異なる可能性がある他のいくつかのケースがあります(.で始まるファイルだけではありません)。さらに、.で始まるファイルをglobと一致させたい場合は、shopt -s dotglobを使用してそれを有効にすることもできます。

1つ目は、foo/にエントリがなく、nullglobを有効にしていない場合、foo/*cpに渡されるリテラルとして返されます。 (この場合)ソースがないため、foo/*cpは文句を言いますが、cp -R foo/には常に少なくともfoo/をコピーする必要があります。 nullglobを有効にした場合、foo/*は何にも展開されないため、cpへの引数が欠落することになります。

考慮すべきもう1つのケースは、foo/に多数のエントリがあるかどうかです。シェルはglobを展開してからプロセスを呼び出しますが、globが展開する引数が多すぎると、エラーが発生します。 cp -R foo/を使用すると、引数は2つだけになります(ただし、おそらく別の場所にターゲットがあります)。

2
Eric Renouf