UNIX 自动交换或替换目录?

No *_*ame 5 unix directory swap move atomic

我有以下问题。我有两个目录,我将它们称为 dir1 和 dir2。它们都填充有文件和子目录。它们都在同一个文件系统上。dir1 的内容是旧的,必须替换为 dir2 的内容。可以丢弃 dir1 的内容。但是,我需要这种替换以原子方式发生。我目前的解决方案如下。

mv dir1 dir1_backup; mv dir2 dir1; rm -rf dir1_backup
Run Code Online (Sandbox Code Playgroud)

如果第一个命令失败,第二个命令将不会运行。这很好。但是,如果第二个命令失败怎么办?dir1 不再存在,我处于无效状态。

实现这一目标的最佳方法是什么?是否可以?

小智 1

我不认为您上面关于如果第一个命令失败第二个命令也会失败的断言是正确的。如果mv dir1 dir1_backup失败,则 dir1 将仍然存在,并使mv dir2 dir1dir2 成为 dir1 的子目录。另外,由于您在第三个命令中传递-frm,因此它将无法删除不存在的目录。

作为参考,三个 bash 运算符(假设此处为 bash)及其作用:

  • ; 无论退出状态如何,在第一次退出后只需执行以下命令。
  • 仅当前一个命令完全退出(即退出状态为 0)时,&& 才会执行以下命令。
  • || 仅当前一个命令不正常退出(即具有非零退出代码)时才执行以下命令。

如果您希望每个命令的执行都依赖于前一个命令的成功执行,那么您可能需要考虑如下内容:

    mv dir1 dir1_backup && mv dir2 dir1 && rm -rf dir1_backup
Run Code Online (Sandbox Code Playgroud)

如果目录的移动是您预期的失败模式,那么在继续删除旧目录内容之前测试移动的返回值或测试预期目录是否存在可能是合理的。如果测试失败,则将旧目录内容移回原处。整体操作会失败,但至少你不会处于无效状态。例如:

    mv dir1 dir1_backup && \
    mv dir2 dir1 && \
    rm -rf dir1_backup || mv dir1_backup dir1
Run Code Online (Sandbox Code Playgroud)

因为我们知道&&只有前一个命令成功退出才会执行后面的命令,所以mv dir2 dir1只有mv dir1 dir1_backup成功才会执行。

此外,rm -rf dir1_backup仅当 dir2 到 dir1 的移动成功时才会执行。但是,如果最后一个退出代码(失败时返回的代码mv dir2 dir1)非零,则该||运算符会导致mv dir1_backup dir1执行。

希望有帮助!如果需要澄清,请告诉我。