3

Given the following situation...

<path>/mydir1/mydir2

...where mydir2 should have overwritten mydir1, but was instead placed inside, and both directories actually have the same filename. How is that fixed?

Attempting to do mv <path>/mydir/mydir/* <path>/mydir/ or mv <path>/mydir <path>/ results in:

mv: cannot move `<path>/mydir/mydir` to a subdirectory of itself, `<path>/mydir`

This seems stupidly simple, but it's late here and I can't figure it out.

There are seventeen such directories to fix (path differs for each, but same mydir name).


To confirm, the error message can be caused with this:

# cd /path/to/directory
# mv mydir/mydir ./
mv: cannot move `mydir/mydir' to a subdirectory of itself, `./mydir'

Also tried:

# mv mydir/mydir/* mydir/
mv: cannot move `mydir/mydir/otherdir1' to a subdirectory of itself, `mydir/otherdir1'
mv: cannot move `mydir/mydir/otherdir2' to a subdirectory of itself, `mydir/otherdir2'

and...

# mv /path/to/directory/mydir/mydir/otherdir1 /path/to/directory/mydir/
mv: cannot move `/path/to/directory/mydir/mydir/otherdir1' to a subdirectory of itself, `/path/to/directory/mydir/otherdir1'

and using a temporary directory:

# mv mydir/mydir ./mydir-temp
# mv mydir-temp/* mydir/
mv: cannot move `mydir-temp/otherdir1' to a subdirectory of itself, `mydir/otherdir1'
mv: cannot move `mydir-temp/otherdir2' to a subdirectory of itself, `mydir/otherdir2'


I found a similar question "How to recursively move all files (including hidden) in a subfolder into a parent folder in *nix?" which suggested that mv bar/{,.}* . would do this.

But this also gives the same errors, as well as confusingly picking up . and .. from somewhere.

# cd mydir
# mv mydir/{,.}* .
mv: cannot move `mydir/otherdir1' to a subdirectory of itself, `./otherdir1'
mv: cannot move `mydir/otherdir2' to a subdirectory of itself, `./otherdir2'
mv: cannot move `mydir/.' to `./.': Device or resource busy
mv: cannot move `mydir/..' to `./..': Device or resource busy
mv: overwrite `./.file'? y


Another similar question "linux mv command weirdness" suggests that mv doesn't overwrite and a copy is required.

# cd mydir
# cp -rf ./mydir/* ./
cp: overwrite `./otherdir1/file1'? y
cp: overwrite `./otherdir1/file2'? y
cp: overwrite `./otherdir1/file3'?

This appears to be working... except there's a lot of files (and dirs) - I don't want to confirm every one! Isn't the f there supposed to prevent this?

Ok, so cp was aliased to cp -i (which I found out with type cp), and bypassed by using \cp -rf ./mydir/* ./ which seems to have worked.

Although I've solved the problem of getting dirs/files from one place to another, I'm still curious as to what's going on with the mv stuff - is this really a deliberate feature as suggested by Warner?

2
  • Something doesn't add up, mv /path/mydir /path/ tells me that "/path/mydir/ and /path/mydir are the same file"., and mv /path/mydir/mydir/* /path/mydir/ works. The only way I can get that "subdirectory of itself" message is if I reverse the command and mv /path/mydir /path/mydir/mydir
    – DerfK
    Dec 15, 2010 at 4:57
  • DerfK, I agree it sounds odd, but I've just run it again and will update the question with the commands... Dec 15, 2010 at 19:09

2 Answers 2

1

First, move the new directory out (with a temp name to avoid conflict), then delete the original directory, then rename the new directory into place. Note: because this will involve deleting things en masse, think it through carefully before just running these commands, and make sure you have a backup first. Also, I've written this with &&s between the commands, so if one fails the rest won't run -- good in a script, but if you're doing this manually it's probably better to just type them sequentially, pay attention, and stop if anything goes wrong.

mv <path>/mydir/mydir <path>/mydir-temp &&
rm -R <path>/mydir &&
mv <path>/mydir-temp <path>/mydir
5
  • I'm confused by the recursive delete command here - if the directory is moved why would it need to be deleted? Dec 15, 2010 at 19:18
  • Also, I tried a variant of this and get the same problem - see latest edit to question. Dec 15, 2010 at 19:22
  • Oops, I had the path in the rm command wrong; I've edited the answer to correct it. Dec 15, 2010 at 19:49
  • Ah, I see what you're doing now. This would however mean that any files in <path>/mydir that aren't in <path>/mydir/mydir would be lost. I guess sometimes that's useful, but not in this case. Dec 15, 2010 at 19:59
  • Are you trying to merge the two mydir directories? I don't think the mv command can do that... Dec 15, 2010 at 20:21
0

Best way to do this is:

for d in `ls -A`; do if [ "$d" != "TTT" ]; then cp -Rf $d TTT; fi; done

copies all directories from current directory recursively in directory TTT except TTT itself. Option -A in ls allows you to consider all hidden directories and files but don't consider special files . and .. and condition "$d" != "TTT" exclude directory TTT so to avoid itself copy. You may write bash script with 2 arguments save to local or system bin and use it when needed.

3
  • You should never parse ls. Please see mywiki.wooledge.org/ParsingLs.
    – Chris Down
    Nov 9, 2012 at 11:23
  • @ChrisDown: That's true. But usually, if you are aware of the existing files on a machine you administer, directly parsing shouldn't be an issue. I have been parsing the output of ls on my system for a long time now, without any problems. But then I know for a fact that none of my files contain any harmful characters. In case of a new or unknown system, yes, NEVER parse the output of ls.
    – darnir
    Nov 9, 2012 at 15:35
  • Considering the alternative is even shorter (for d in *), and more intuitive, it just seems really strange to do regardless of whether it usually works fine.
    – Chris Down
    Nov 9, 2012 at 15:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .