cp コマンド: *nix にファイル フォルダーを正しくコピーする

cp コマンド: *nix にファイル フォルダーを正しくコピーする

この記事では、 ワイルドカード コピー時のあいまいなコマンド動作 cp コピーするときの方法と、スキップやクラッシュを発生させずに大量のファイルを正しくコピーできる方法について説明します。

/source フォルダーから /target フォルダーにすべてをコピーする必要があるとします。

最初に思い浮かぶのは次のようなことです。

cp /source/* /target

すぐにこのコマンドを次のように修正してみましょう。

cp -a /source/* /target

キー -a すべての属性、権限のコピーを追加し、再帰を追加します。 権利の正確な複製が必要ない場合は、キーで十分です -r.

コピー後、すべてのファイルがコピーされたわけではないことがわかります。次のようなドットで始まるファイルです。

.profile
.local
.mc

など。

これはなぜ起こったのでしょうか。

ワイルドカードはシェルによって処理されるため (bash 典型的な場合)。 デフォルトでは、bash はドットで始まるすべてのファイルを非表示として扱うため無視します。 この動作を回避するには、動作を変更する必要があります bash コマンドを使用して:

shopt -s dotglob

この動作の変更が再起動後も持続するようにするには、このコマンドを使用して、フォルダー内に wildcard.sh ファイルを作成します。 /etc/profile.d (ディストリビューションには別のフォルダーがある可能性があります)。

また、ソース ディレクトリにファイルがない場合、シェルはアスタリスクの代わりに何も置き換えることができず、コピーもエラーで失敗します。 この状況に対しては選択肢があります failglob и nullglob。 設定する必要があります failglob、コマンドが実行できなくなります。 nullglob 一致が見つからなかったワイルドカードを含む文字列を空の文字列 (長さ XNUMX) に変換するため、機能しません。 cp エラーが発生します。

ただし、フォルダー内に数千以上のファイルがある場合は、ワイルドカードによるアプローチを完全に放棄する必要があります。 事実は、 bash ワイルドカードを次のような非常に長いコマンドラインに展開します。

cp -a /souce/a /source/b /source/c …… /target

コマンドラインの長さには制限があり、次のコマンドを使用して確認できます。

getconf ARG_MAX

コマンドラインの最大長をバイト単位で取得してみましょう。

2097152

Или:

xargs --show-limits

次のような結果が得られます。

….
Maximum length of command we could actually use: 2089314
….

したがって、ワイルドカードをまったく使用しないようにしましょう。

ちょっと書いてみましょう

cp -a /source /target

そしてここで私たちは行動の曖昧さに直面します cp。 /target フォルダーが存在しない場合は、必要なものを取得します。

ただし、ターゲット フォルダーが存在する場合、ファイルは /target/source フォルダーにコピーされます。

/target フォルダーには必要なファイルが含まれている可能性があり、たとえば /target 内のファイルを /source のファイルで補うことが目的であるため、常に事前に /target フォルダーを削除できるわけではありません。

たとえば、ソース フォルダーと宛先フォルダーの名前が同じである場合、/source から /home/source にコピーする場合は、次のコマンドを使用できます。

cp -a /source /home

コピー後、/home/source 内のファイルは /source のファイルで補完されます。

これは論理的な問題です。フォルダーの名前が同じであれば、宛先ディレクトリにファイルを追加できますが、異なる場合は、ソース フォルダーが宛先ディレクトリ内に配置されます。 ワイルドカードなしで cp を使用して /source から /target にファイルをコピーするにはどうすればよいですか?

この有害な制限を回避するために、次のような非自明な解決策を使用します。

cp -a /source/. /target

DOS や Linux に詳しい人はすでにすべてを理解しているでしょう。各フォルダー内には 2 つの目に見えないフォルダー「.」があります。 および「..」は、現在のディレクトリおよびそれ以上のディレクトリへの疑似フォルダー リンクです。

  • コピー時 cp 存在を確認し、/target/ の作成を試みます。
  • そのようなディレクトリが存在し、それは /target です
  • /source のファイルは /target に正しくコピーされます。

したがって、思い出の中に、あるいは壁に、大胆な額縁に入れて飾ってください。

cp -a /source/. /target

このコマンドの動作は明らかです。 ファイルが XNUMX 万個ある場合でも、ファイルがまったくない場合でも、すべてがエラーなしで動作します。

所見

コピーする必要がある場合 すべて あるフォルダーから別のフォルダーにファイルを移動する場合、ワイルドカードは使用しません。代わりにワイルドカードを使用することをお勧めします。 cp ソースフォルダーの末尾にピリオドを組み合わせます。 これにより、隠しファイルを含むすべてのファイルがコピーされ、数百万のファイルでも、ファイルがまったく存在しなくても失敗することはありません。

後書き

vmスパイク 同様の結果が得られるコマンド バージョンを提案しました。

cp -a -T /source /target

オズ・アレックス

cp -aT /source /target

注: 大文字と小文字 T 意味があります。 混同すると完全にゴミになってしまい、コピーの方向が変わってしまいます。
ありがとう:

  • 企業 RUVDS.COM サポートとハブレのブログで公開する機会を求めてください。
  • 画像ごと トリプルコンセプト。 画像は非常に大きくて詳細なので、別のウィンドウで開くことができます。

PS 間違いに気づいた場合は、プライベート メッセージで送信してください。 このために私はカルマを増やします。

cp コマンド: *nix にファイル フォルダーを正しくコピーする

出所: habr.com

コメントを追加します