5

次の問題があります。dir1 および dir2 と呼ぶ 2 つのディレクトリがあります。どちらにも、ファイルとサブディレクトリの両方が取り込まれています。それらは両方とも同じファイルシステムにあります。dir1 の内容は古いため、dir2 の内容に置き換える必要があります。dir1 の内容は破棄できます。ただし、この置換をアトミックに行う必要があります。私の現在の解決策は次のとおりです。

mv dir1 dir1_backup; mv dir2 dir1; rm -rf dir1_backup

最初のコマンドが失敗すると、2 番目のコマンドは実行されません。これはいい。しかし、2 番目のコマンドが失敗した場合はどうなるでしょうか。dir1 はもう存在せず、無効な状態のままです。

これを達成するための最良の方法は何ですか?出来ますか?

4

3 に答える 3

1

最初のコマンドが失敗した場合、2番目のコマンドが失敗するという上記の主張は真実ではないと思います。失敗した場合mv dir1 dir1_backup、dir1 はまだ存在し、mv dir2 dir1dir2 を dir1 のサブディレクトリにします。また、3 番目のコマンドで を渡し-fているためrm、存在しないディレクトリの削除は黙って失敗します。

参考までに、3 つの bash 演算子 (ここでは bash を想定) とその機能:

  • ; 終了ステータスに関係なく、最初の終了後に次のコマンドを実行するだけです。
  • && は、前のコマンドが正常に終了した (つまり、終了ステータスが 0 だった) 場合にのみ、次のコマンドを実行します。
  • || は、前のコマンドが正常に終了しなかった場合 (つまり、ゼロ以外の終了コードを持っていた場合) にのみ、次のコマンドを実行します。

各コマンドの実行を前のコマンドの実行の成功に依存させたい場合は、次のようなことを検討する必要があります。

    mv dir1 dir1_backup && mv dir2 dir1 && rm -rf dir1_backup

ディレクトリの移動が想定どおりの失敗モードである場合は、古いディレクトリの内容の削除に進む前に、移動の戻り値をテストするか、予想されるディレクトリの存在をテストするのが妥当な場合があります。テストが失敗した場合は、古いディレクトリの内容を元に戻します。全体的な操作は失敗しますが、少なくとも無効な状態にはなりません。例えば:

    mv dir1 dir1_backup && \
    mv dir2 dir1 && \
    rm -rf dir1_backup || mv dir1_backup dir1

&&は、前のコマンドが正常に終了した場合にのみ次のコマンドを実行することがわかっているため、成功したmv dir2 dir1場合にのみ実行されmv dir1 dir1_backupます。

さらに、rm -rf dir1_backupdir2 から dir1 への移動が成功した場合にのみ実行されます。ただし、最後の終了コード (mv dir2 dir1失敗した場合に返されるコード) がゼロ以外の場合、||オペレーターはmv dir1_backup dir1実行を引き起こします。

それが役立つことを願っています! 説明が必要な場合はお知らせください。

于 2013-06-14T17:16:04.603 に答える