Friday, April 19, 2024
 Popular · Latest · Hot · Upcoming
11
rated 0 times [  11] [ 0]  / answers: 1 / hits: 878  / 3 Years ago, tue, july 20, 2021, 10:52:21

I have a folder structure:


/mnt/data/mydata/mydata/several-files-and-folders-here


I would like it to instead be:


/mnt/data/mydata/several-files-and-folders-here


I tried mv but it complains the folder isn't empty, and I wasn't able to find a feasible fast solution that I understood, I'm still new to learning Linux. How would one fix this correctly?


More From » files

 Answers
1

Moving every file in the subdirectory into the parent is one way, but if there are a huge number of entries in /mnt/data/mydata/mydata/, and that's the only entry in /mnt/data/mydata, you might consider this sequence of 3 metadata operations that doesn't change the contents of the big directory, just moves it to a different place in the filesystem. And removes 1 entry from a small directory then unlinks it.


Thus it won't affect the ctime of any of the files in the subdirectory or even have to list the contents of that big directory.


 mv  /mnt/data/mydata            /mnt/data/mydata.old   # rename parent
mv /mnt/data/mydata.old/mydata /mnt/data/mydata # subdir -> sibling of parent
rmdir /mnt/data/mydata.old # fails if not empty

The directory inode that was originally /mnt/data/mydata/mydata is now /mnt/data/mydata, and its contents haven't changed. If it contained millions of files, that's faster and takes less i/o. But more typing because mv won't invent a temporary name for you.


If the original /mnt/data/mydata wasn't empty, you can still do this but instead of rmdir, mv /mnt/data/mydata.old/* /mnt/data/mydata/. If it had a couple entries vs. a couple million for the child directory, that's saving some I/O.


You do need write access to /mnt/data, which the other way doesn't need. But this doesn't need write access to /mnt/data/mydata/mydata.


Script this however you like, and/or cd and use relative paths. Pick any temporary name you want, like foo or tmp, or xyz123. (If other users can write /mnt/data, and you're scripting it, check on what mv will do if they create a file with the same random name you pick; or use mktemp -p /mnt/data/ to get a temp dir there to move the child mydata into while you unlink /mnt/data/mydata.)


It has the downside that there is a moment between operations when no /mnt/data/mydata exists at all. Unless there's a shell wrapper for the renameat2 system call with RENAME_EXCHANGE to atomically exchange two paths. (Linux kernel 3.15, glibc 2.28, so it's been around for a while, but rename(1) and mv(1) don't have options to use it.)


If you're running a server, this might matter to you, otherwise you likely don't care.




Interactively, you might also use imv /mnt/data/mydata to interactively edit the path with readline line-editing (the same as bash uses for command-line editing.)


[#23] Tuesday, July 20, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
mance

Total Points: 198
Total Questions: 105
Total Answers: 128

Location: South Georgia
Member since Mon, Aug 16, 2021
3 Years ago
mance questions
Wed, Jul 14, 21, 12:04, 3 Years ago
Thu, Sep 1, 22, 15:22, 2 Years ago
Sun, Jun 13, 21, 05:50, 3 Years ago
Sun, Nov 21, 21, 11:02, 2 Years ago
;