コマンド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つのディレクトリレベルを取得します)。
デフォルトでは、bashのグロブには.
で始まるファイル名が含まれていません。したがって、*
を指定すると、「.
」で始まるファイルなしで再帰的にコピーするように求められます。 *
を指定しない場合、「.
」ファイルを含むすべてがコピーされます。
あなたが持っている他の答えに加えて、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つだけになります(ただし、おそらく別の場所にターゲットがあります)。