ディレクトリをスキップしてファイルのみをcpする

ディレクトリをスキップしてファイルのみをcpする

cp を使用して、空のディレクトリがあるディレクトリからファイルをコピーすると、エラーが返され、スクリプトが失敗します。

エラーを返さずにディレクトリをスキップする方法はありますか? エラー値にエラーを反映させたいのですが、そこに空のディレクトリがある場合は、エラーとして報告されることなく、単にスキップされる必要があります。

再帰フラグを追加することもできます-rが、ディレクトリをコピーしたくない場合はどうすればいいでしょうか?するエラーを報告しますか?

答え1

可能であれば、空のフォルダーを除外するオプション -m があるので、cp の代わりに rsync を使用することをお勧めします。例:

rsync -am <origin> <destination>

コマンドの説明シェルの説明

私は -a オプションを使用していますが、これは多くの優れたデフォルト アクションを実行するためです。ただし、必要に応じて -r オプションも使用でき、これにより再帰モードのみが設定されます。

[コメントを追加]

cp でこれを行う方法は知りません。少なくともマニュアルページには、これを行うオプションは表示されていません。コマンドを使用してfindコピーするファイル/ディレクトリのリストを検索し、それを cp に渡すことで、より複雑な解決策を実行できる可能性がありますが、rsync よりもはるかに複雑になります。rsync は多くの Linux でほぼ標準です。

答え2

cp確かにファイルだけを取得するオプションはありませんが、凶暴なfind前述のように、を と一緒に使用できますcp。実際、これは非常に簡単です。

# Copy only files
find /path/to/file -type f -execdir cp "{}" /dest/path ";"

または:

# Copy everything except directories
find /path/to/file -not -type d -execdir cp "{}" /dest/path ";"

説明

findは、必要なファイルを検索するツールです。最初のオプションでは、-type f通常のファイルのみを返すように を設定します。2 番目のオプションでは、-not -type dディレクトリ以外のすべてを取得するように を設定します。 は、find渡された引数を1 つずつ結果エントリに-execdir置き換えて実行し{}、 が見つかったらコマンドを停止します;(;はエスケープする\;か でエスケープする必要があります";"。そうしないと、シェルによって展開される可能性があります)。

-execdirは、ファイルのフォルダーを「作業ディレクトリ」としてコマンドを実行します。 の代わりに が推奨されます-exec。以下を確認してください。

オプション-typeのドキュメント:

-タイプc

ファイルのタイプは c: です。

b: ブロック(バッファリング)スペシャル

c: 文字(バッファなし)特殊

d: ディレクトリ

p: 名前付きパイプ (FIFO)

f: 通常ファイル

l: シンボリック リンク。-L オプションまたは -follow オプションが有効な場合、シンボリック リンクが壊れていない限り、これは真になりません。-L が有効なときにシンボリック リンクを検索する場合は、-xtype を使用します。

s: ソケット

D: ドア (Solaris)

オプション-notのドキュメント:

expr が偽の場合は真。この文字は通常、シェルによる解釈から保護する必要もあります。

-ない

! expr と同じですが、POSIX に準拠していません。

オプション-execdirのドキュメント:

-実行指示 ;

実行する指示;0 ステータスが返された場合は true。find への後続の引数はすべて、';' で構成される引数が検出されるまで、コマンドへの引数として扱われます。文字列 '{}' は、コマンドへの引数に出現するすべての場所で、処理中の現在のファイル名に置き換えられます [...]。これらの構造は両方とも、シェルによる展開から保護するために、エスケープ ('\' を使用) または引用符で囲む必要がある場合があります。指定されたコマンドは、一致したファイルごとに 1 回実行されます。コマンドは開始ディレクトリで実行されます。-exec アクションの使用には避けられないセキュリティ上の問題があるため、代わりに -execdir オプションを使用する必要があります。

-execdir指示 ;

-execと同様だが、指定されたコマンドは一致したファイルを含むサブディレクトリから実行されます、これは通常、find を起動したディレクトリではありません。これは、一致したファイルへのパスを解決する際に競合状態を回避するため、コマンドを呼び出すためのはるかに安全な方法です。[...] このオプションを使用する場合は、$PATH 環境変数が '.' を参照していないことを確認する必要があります。そうしないと、攻撃者は、-execdir を実行するディレクトリに適切な名前のファイルを残して、任意のコマンドを実行できます。$PATH に空のエントリや絶対ディレクトリ名ではないエントリがある場合も同様です。

https://linux.die.net/man/1/find

関連情報