Portable, race-free equivalent of mv -T DIR1 DIR2?












2















It seems mv -T is a GNU extension to mv.



Is there a robust way (race-free, portable, and otherwise without "gotchas") to do the equivalent of mv -T dir1 dir2?



To be clear:




  • I DO NOT want this to ever result in dir2/dir1.
    If dir2 exists, I want the command to fail. If dir1 is moved at all, it must become dir2.


  • I DO NOT want to move out every child one-by-one. I want to move the directory itself.


  • I DO want to avoid race conditions. It's trivial to test if dir2 exists first, but then it might be created after the check but before the move.











share|improve this question























  • I don't think it's possible to satisfy "If dir2 exists, I want the command to fail" portably; POSIX requires rename to delete an empty dir2 and succeed.

    – Michael Homer
    2 hours ago











  • The spec text: "If the old argument points to the pathname of a directory, the new argument shall not point to the pathname of a file that is not a directory. If the directory named by the new argument exists, it shall be removed and old renamed to new. [...] If new names an existing directory, it shall be required to be an empty directory.". That also applies to renameat. I don't believe there can be any portable method to rename a file that does not go through that path. Given that, which of your requirements can you relax? What sorts of race condition are you concerned with?

    – Michael Homer
    2 hours ago













  • Related: mv: Move file only if destination does not exist

    – Freddy
    2 hours ago













  • @MichaelHomer: Interesting, thanks. The race condition I'm trying to avoid is dir1 landing inside dir2, which can happen if multiple processes try to run this command at once. However, I guess it would be fine if an empty dir2 were deleted. Would that help? Also, if there's still no single POSIX solution, I'd be interested in knowing if there are even platform-specific solution that I can call. E.g. is there a solution that works on Mac, let alone other platforms? I haven't found any.

    – Mehrdad
    2 hours ago













  • The renameat2 system call takes a flag argument and one such flag is RENAME_NOREPLACE which causes it to: "Don't overwrite newpath of the rename. Return an error if newpath already exists." ... But that doesn't really satisfy "portable", so not sure it solves your problem...

    – filbranden
    1 hour ago


















2















It seems mv -T is a GNU extension to mv.



Is there a robust way (race-free, portable, and otherwise without "gotchas") to do the equivalent of mv -T dir1 dir2?



To be clear:




  • I DO NOT want this to ever result in dir2/dir1.
    If dir2 exists, I want the command to fail. If dir1 is moved at all, it must become dir2.


  • I DO NOT want to move out every child one-by-one. I want to move the directory itself.


  • I DO want to avoid race conditions. It's trivial to test if dir2 exists first, but then it might be created after the check but before the move.











share|improve this question























  • I don't think it's possible to satisfy "If dir2 exists, I want the command to fail" portably; POSIX requires rename to delete an empty dir2 and succeed.

    – Michael Homer
    2 hours ago











  • The spec text: "If the old argument points to the pathname of a directory, the new argument shall not point to the pathname of a file that is not a directory. If the directory named by the new argument exists, it shall be removed and old renamed to new. [...] If new names an existing directory, it shall be required to be an empty directory.". That also applies to renameat. I don't believe there can be any portable method to rename a file that does not go through that path. Given that, which of your requirements can you relax? What sorts of race condition are you concerned with?

    – Michael Homer
    2 hours ago













  • Related: mv: Move file only if destination does not exist

    – Freddy
    2 hours ago













  • @MichaelHomer: Interesting, thanks. The race condition I'm trying to avoid is dir1 landing inside dir2, which can happen if multiple processes try to run this command at once. However, I guess it would be fine if an empty dir2 were deleted. Would that help? Also, if there's still no single POSIX solution, I'd be interested in knowing if there are even platform-specific solution that I can call. E.g. is there a solution that works on Mac, let alone other platforms? I haven't found any.

    – Mehrdad
    2 hours ago













  • The renameat2 system call takes a flag argument and one such flag is RENAME_NOREPLACE which causes it to: "Don't overwrite newpath of the rename. Return an error if newpath already exists." ... But that doesn't really satisfy "portable", so not sure it solves your problem...

    – filbranden
    1 hour ago
















2












2








2








It seems mv -T is a GNU extension to mv.



Is there a robust way (race-free, portable, and otherwise without "gotchas") to do the equivalent of mv -T dir1 dir2?



To be clear:




  • I DO NOT want this to ever result in dir2/dir1.
    If dir2 exists, I want the command to fail. If dir1 is moved at all, it must become dir2.


  • I DO NOT want to move out every child one-by-one. I want to move the directory itself.


  • I DO want to avoid race conditions. It's trivial to test if dir2 exists first, but then it might be created after the check but before the move.











share|improve this question














It seems mv -T is a GNU extension to mv.



Is there a robust way (race-free, portable, and otherwise without "gotchas") to do the equivalent of mv -T dir1 dir2?



To be clear:




  • I DO NOT want this to ever result in dir2/dir1.
    If dir2 exists, I want the command to fail. If dir1 is moved at all, it must become dir2.


  • I DO NOT want to move out every child one-by-one. I want to move the directory itself.


  • I DO want to avoid race conditions. It's trivial to test if dir2 exists first, but then it might be created after the check but before the move.








filesystems mv posix






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 2 hours ago









MehrdadMehrdad

1,18141432




1,18141432













  • I don't think it's possible to satisfy "If dir2 exists, I want the command to fail" portably; POSIX requires rename to delete an empty dir2 and succeed.

    – Michael Homer
    2 hours ago











  • The spec text: "If the old argument points to the pathname of a directory, the new argument shall not point to the pathname of a file that is not a directory. If the directory named by the new argument exists, it shall be removed and old renamed to new. [...] If new names an existing directory, it shall be required to be an empty directory.". That also applies to renameat. I don't believe there can be any portable method to rename a file that does not go through that path. Given that, which of your requirements can you relax? What sorts of race condition are you concerned with?

    – Michael Homer
    2 hours ago













  • Related: mv: Move file only if destination does not exist

    – Freddy
    2 hours ago













  • @MichaelHomer: Interesting, thanks. The race condition I'm trying to avoid is dir1 landing inside dir2, which can happen if multiple processes try to run this command at once. However, I guess it would be fine if an empty dir2 were deleted. Would that help? Also, if there's still no single POSIX solution, I'd be interested in knowing if there are even platform-specific solution that I can call. E.g. is there a solution that works on Mac, let alone other platforms? I haven't found any.

    – Mehrdad
    2 hours ago













  • The renameat2 system call takes a flag argument and one such flag is RENAME_NOREPLACE which causes it to: "Don't overwrite newpath of the rename. Return an error if newpath already exists." ... But that doesn't really satisfy "portable", so not sure it solves your problem...

    – filbranden
    1 hour ago





















  • I don't think it's possible to satisfy "If dir2 exists, I want the command to fail" portably; POSIX requires rename to delete an empty dir2 and succeed.

    – Michael Homer
    2 hours ago











  • The spec text: "If the old argument points to the pathname of a directory, the new argument shall not point to the pathname of a file that is not a directory. If the directory named by the new argument exists, it shall be removed and old renamed to new. [...] If new names an existing directory, it shall be required to be an empty directory.". That also applies to renameat. I don't believe there can be any portable method to rename a file that does not go through that path. Given that, which of your requirements can you relax? What sorts of race condition are you concerned with?

    – Michael Homer
    2 hours ago













  • Related: mv: Move file only if destination does not exist

    – Freddy
    2 hours ago













  • @MichaelHomer: Interesting, thanks. The race condition I'm trying to avoid is dir1 landing inside dir2, which can happen if multiple processes try to run this command at once. However, I guess it would be fine if an empty dir2 were deleted. Would that help? Also, if there's still no single POSIX solution, I'd be interested in knowing if there are even platform-specific solution that I can call. E.g. is there a solution that works on Mac, let alone other platforms? I haven't found any.

    – Mehrdad
    2 hours ago













  • The renameat2 system call takes a flag argument and one such flag is RENAME_NOREPLACE which causes it to: "Don't overwrite newpath of the rename. Return an error if newpath already exists." ... But that doesn't really satisfy "portable", so not sure it solves your problem...

    – filbranden
    1 hour ago



















I don't think it's possible to satisfy "If dir2 exists, I want the command to fail" portably; POSIX requires rename to delete an empty dir2 and succeed.

– Michael Homer
2 hours ago





I don't think it's possible to satisfy "If dir2 exists, I want the command to fail" portably; POSIX requires rename to delete an empty dir2 and succeed.

– Michael Homer
2 hours ago













The spec text: "If the old argument points to the pathname of a directory, the new argument shall not point to the pathname of a file that is not a directory. If the directory named by the new argument exists, it shall be removed and old renamed to new. [...] If new names an existing directory, it shall be required to be an empty directory.". That also applies to renameat. I don't believe there can be any portable method to rename a file that does not go through that path. Given that, which of your requirements can you relax? What sorts of race condition are you concerned with?

– Michael Homer
2 hours ago







The spec text: "If the old argument points to the pathname of a directory, the new argument shall not point to the pathname of a file that is not a directory. If the directory named by the new argument exists, it shall be removed and old renamed to new. [...] If new names an existing directory, it shall be required to be an empty directory.". That also applies to renameat. I don't believe there can be any portable method to rename a file that does not go through that path. Given that, which of your requirements can you relax? What sorts of race condition are you concerned with?

– Michael Homer
2 hours ago















Related: mv: Move file only if destination does not exist

– Freddy
2 hours ago







Related: mv: Move file only if destination does not exist

– Freddy
2 hours ago















@MichaelHomer: Interesting, thanks. The race condition I'm trying to avoid is dir1 landing inside dir2, which can happen if multiple processes try to run this command at once. However, I guess it would be fine if an empty dir2 were deleted. Would that help? Also, if there's still no single POSIX solution, I'd be interested in knowing if there are even platform-specific solution that I can call. E.g. is there a solution that works on Mac, let alone other platforms? I haven't found any.

– Mehrdad
2 hours ago







@MichaelHomer: Interesting, thanks. The race condition I'm trying to avoid is dir1 landing inside dir2, which can happen if multiple processes try to run this command at once. However, I guess it would be fine if an empty dir2 were deleted. Would that help? Also, if there's still no single POSIX solution, I'd be interested in knowing if there are even platform-specific solution that I can call. E.g. is there a solution that works on Mac, let alone other platforms? I haven't found any.

– Mehrdad
2 hours ago















The renameat2 system call takes a flag argument and one such flag is RENAME_NOREPLACE which causes it to: "Don't overwrite newpath of the rename. Return an error if newpath already exists." ... But that doesn't really satisfy "portable", so not sure it solves your problem...

– filbranden
1 hour ago







The renameat2 system call takes a flag argument and one such flag is RENAME_NOREPLACE which causes it to: "Don't overwrite newpath of the rename. Return an error if newpath already exists." ... But that doesn't really satisfy "portable", so not sure it solves your problem...

– filbranden
1 hour ago












0






active

oldest

votes











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f503036%2fportable-race-free-equivalent-of-mv-t-dir1-dir2%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f503036%2fportable-race-free-equivalent-of-mv-t-dir1-dir2%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Loup dans la culture

How to solve the problem of ntp “Unable to contact time server” from KDE?

ASUS Zenbook UX433/UX333 — Configure Touchpad-embedded numpad on Linux