BASHを使い始めたばかりなので、ディレクトリのすべての内容を別のディレクトリに移動できます。しかし、問題は、ディレクトリをマージすることを期待していたことです。このスクリプトを実行するためにcronジョブを使用しています。
#!/bin/bash
shopt -s dotglob nullglob
mv mv_schedule/* public_html/
ソース:/mv_schedule/
(フォルダー/ファイルを含む)
/files/
4.html
5.html
/assets/
sitemap.xml
宛先:/public_html/
(以前のフォルダーは既に存在します)
/files/
1.html
2.html
3.html
/assets/
sitemap.xml
だから私が欲しいのは、/mv_schedule/
内のそれらのディレクトリからのすべての新しいファイルを/public_html/
内のファイルとマージし、そこにすでに存在するファイルを次のファイルに置き換えることです/mv_schedule/
から。
現在のスクリプトでこれを試してみると、現在、このエラーが電子メールで返されています。
mv: cannot move `mv_schedule/assets' to `public_html/assets': Directory not empty
どうすればこれを修正できますか?
エラーメッセージが示しているのは、アセットディレクトリ内にファイルがあるため、アセットディレクトリを移動できないことです。 mvディレクトリとは、コピーを作成してから消去することを意味しますが、まだいくつかのファイルが含まれているため、削除できません。つまり、アセット内のファイル、およびアセット内のサブディレクトリとサブディレクトリ内のファイル(存在する場合)もmvする必要があります。ただし、発行されたmvコマンドは、mv_schedule内のサブディレクトリ(アセットなど)内に存在するものではなく、mv_scheduleディレクトリ内に存在するもののみをコピー(および消去)できます。
必要なのは、ディレクトリツリーを最後の一葉まで降ろしてコピーするコマンドです。これは、rm、chmod、chownの-rまたは-Rオプションのようなものです。ただし、mvにはそのようなオプションがないため、コマンドfindを使用する必要があります。このコマンドは、指定したルートからディレクトリツリー全体を下に移動し、指定したアクションを実行します。あなたの場合、適切なコマンドは次のとおりです。
SOURCE_DIR=$1
TARGET_DIR=$2
find $SOURCE_DIR -name '*' -type f -exec mv -f {} $TARGET_DIR \;
これにより、すべてのファイルが1つのターゲットディレクトリに積み上げられます。ソースディレクトリとターゲットディレクトリを入力行パラメータとしてbashスクリプトに渡したと想定しています。 -fオプションは、上書きの場合に確認を求めないようにします。これを-n(上書きしない)または-i(上書きする前に確認する)に変更できます。
代わりにディレクトリ構造を保持したい場合は、コマンドcpにはディレクトリツリーを下降する機能があることに注意してください。このコマンドにはツリーを下降する機能もあるため、このコマンドの後にrmを使用できます。考えられるコマンドのセットは次のとおりです。
SOURCE_DIR=$1
TARGET_DIR=$2
cp -a $SOURCE_DIR $TARGET_DIR
rm -rf $SOURCE_DIR
Cpの-aオプションに注意してください。タイムスタンプと所有権を保持します。そのようなことを気にしない場合は、代わりに-Rを使用できます。
Unixセクションにはもっと一般的な この問題の議論 があります。
cpコマンドの-l
オプションを使用できます。これにより、完全なファイルではなく、同じファイルシステム上に ハードリンク のファイルが作成されます。データコピー。次のコマンドは、フォルダsource/folder
を親フォルダ(destination
)にコピーします。このフォルダには、folder
という名前のディレクトリがすでに含まれています。
cp -rl source/folder destination
rm -r source/folder
ノート:
-P
(--no-dereference
-シンボリックリンクを逆参照しない)または-a
(--archive
-すべてのメタデータを保持し、-P
オプションも含む)を使用することもできます。-l
)またはrsyncベースのソリューションよりもはるかに高速です。Palswimからの優れた回答。 (また、自分自身を賛成するために必要な最後の2つのポイントに対する賛成に感謝します!)
Cp -rl; rmは問題を解決し、最小限のI/Oで解決します(cpとrsyncはばかげてその点で高価です)。
これには2つの小さな問題があります。