17

I have a little question here.

If I have two files, say filea and fileb, mv filea fileb would

  • delete fileb
  • rename filea to fileb

Then if I have two directories, say dira and dirb, mv dira dirb would

  • move dira into dirb (it will become dirb/dira)

Noting that in both cases there are no notice or message, then this is pretty inconsistent to me. I think mv dira dirb should just overwrite dirb with the contents of dira (or merge the two directories under a directory named dirb).

I remember reading somewhere that a directory name with a slash (like dira/) is treated like a directory, and name with no slash (like dira) is treated like a file (to certain extents, of course). Anyway now I want to make the shell (zsh and possibly bash) respect my notation of a directory by using a slash. Is there a terminal option which enable me to enforce that?

To clarify, here is my desired behaviour:

  • mv dira dirb results in dirb being overwritten with the contents of dira
  • mv dira dirb/ results in dira being moved into dirb (in dirb/dira)

Has anyone thought the same way as me? Or am I just weird?

2
  • 2
    I think your desired behavior would be rather dangerous.
    – starblue
    Aug 20, 2010 at 14:36
  • @starblue: yes I agree that it is dangerous, but I'd rather live with something dangerous, than inconsistency
    – phunehehe
    Aug 21, 2010 at 15:40

3 Answers 3

11

Yes, this is a bit inconsistent, even within the GNU tools.

One problem with your proposal is that non-empty directories cannot be removed. Apart from that, -T (in GNU land, anyway) approximates what you want (the first case):

$ ls dira/ dirb/
dira/:
a

dirb/:
b
$ mv -iT dira/ dirb/
mv: overwrite `dirb/'? y
mv: cannot move `dira/' to `dirb/': Directory not empty
$ rm dirb/b 
$ mv -iT dira/ dirb/
mv: overwrite `dirb/'? y
$ ls dira/ dirb/
ls: cannot access dira/: No such file or directory
dirb/:
a
1
  • You could also add an alias, e.g. alias ren=mv -T.
    – Mikel
    May 13, 2011 at 3:57
1

If you just want to move everything from dira to dirb you can run mv dira/* dirb.

As per mv man page on my HP-UX.

The mv command moves:

+ One or more directory subtrees (directory1, [directory2, ...]) to a new or existing directory (dest-directory).

3
  • 3
    Your command would miss all dotfiles.
    – qbi
    Aug 20, 2010 at 12:21
  • Who needs dot files anyway ;) Aug 20, 2010 at 13:45
  • 1
    And if it's an issue, shopt -s dotglob in bash will fix that.
    – David Z
    Aug 21, 2010 at 6:41
0

The following are solutions to obtain an overall more consistent behaviors (at least with the mv and cp commands).

For the move (mv) command

One can get a slightly more consistent behavior by using the -i option:

mv -i SOURCE DEST

This would warn and ask confirmation when filea would overwrite an already existing fileb but would give no warning in any of the other cases, that is, one gets a warning and confirmation only when data loss is about to happen.

$ mv -i filea fileb :

  • if fileb does not already exist, filea is silently renamed to fileb
  • if fileb already exist, confirmation is requested before overwriting fileb with filea

$ mv -i dira dirb :

  • if dirb does not already exist, dira is silently renamed to dirb
  • if dirb already exist, dira is silently moved into dirb

A permanent solution is to create an alias: $ alias mv='mv -i'

For the copy (cp) command

For the cp command a similar -i option exists. However cp SOURCE DEST would not behave as mv -i SOURCE DEST if SOURCE is a directory, because cp would omit any directory if the -r option is not specified.

So, to get a similar behavior as with mv -i one can rather use the following:

$ cp -ir SOURCE DEST

This would treat files and directory similarly (as the mv -i command would) and would warn and ask confirmation before overwriting.

$ cp -ir filea fileb :

  • if fileb does not already exist, filea is silently copied to fileb
  • if fileb already exist, confirmation is requested before overwriting fileb with a copy of filea

$ cp -ir dira dirb :

  • if dirb does not already exist, dira is silently copied to dirb
  • if dirb already exist, dira is silently copied into dirb

A permanent solution here is to create an alias: $ alias cp='cp -ir'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.