I have a for loop on which I have directories that the mv command will apply the same name to its directories, other directories have different names, for example:

for i in {1..3};do
mv hg/ hg

Sometimes hg/ directory will differ to something else (for example dir/ as the loop proceeds) and the loop works when the names are different, but when the names are the same I get the error:

mv: cannot move ‘hg/’ to a subdirectory of itself, ‘hg/hg’

I would like ignore this behavior and make mv just "pretend" the directories have the same name and proceed with the loop. Please note that hg and dir are just examples, the real directories have different names for every iteration of the loop.


1 Answer 1


If you want to avoid trying to rename a directory to itself, you can protect against that with a test condition

[ "$src" != "$dst" ] && mv -f "$src" "$dst"

If you think that one of the directory names might have a trailing slash and the other might not, then remove any trailing slash before applying the test

[ "${src%/}" != "${dst%/}" ] && mv -f "$src" "$dst"

Another more thorough but non-POSIX solution checks whether the two paths reference the same device and inode (i.e. are they the same item regardless of path)

[ ! "$src" -ef "$dst ] && mv -f "$src" "$dst"

Be aware that this will correctly fail when $src and $dst are visibly different but reference the same filesystem item, and therefore this test may not be suitable in many situations. For example, this will print "Entries 'thisname' and 'another' are the same"

src=thisname dst=another
touch "$src"
ln "$src" "$dst"
[ "$src" -ef "$dst" ] && printf "Entries '%s' and '%s' are the same\n" "$src" "$dst"

You must log in to answer this question.

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