0

In RHEL 9,

  1. The command cp -a /somedir/. . executes to copy all files in 'somedir' directory (not the directory itself) to the current directory.

  2. The command mv /somedir/. . though yields the error 'cannot move: Device or Resource busy'.

  3. The commands mv /somedir/ . and mv /somedir . result in moving directory 'somedir' to the present directory.

Questions;

  1. Why does the second command result in an error?

  2. Without the use of * is there a way to move only the contents of directory somedir and not the directory itself to the current directory using mv command?

  3. What is the difference between /path/to/file/ , /path/to/file/. and /path/to/file in Linux specifically RHEL and RHEL like distributions?

1
  • also consider rsync behavior that is specific in those cases Jan 22 at 6:36

1 Answer 1

0

The path ending in / is the same as /. so both the first and second would fail if you used mv because you can't move (or modify in most ways) the directory .. The first does not give this error, because the -a option to cp tells it to recursively copy, so it doesn't try to modify the directory, just copy what is in it.

If you want to move a directory, don't include the trailing /.

You can easily move the contents of a directory without * -- just list every filename. Of course, as the shell expands * to every filename anyway, this would be the same thing, so I'm not sure what the point is of avoiding *.

You could also use filename completion to expand the filenames on the command line -- in bash, one way to do that would be to use esc {

5
  • Though using * is problematic in that it doesn't usually include dotfiles by default. And the workarounds are hairy since they need to avoid ... In Bash, you could use shopt -s dotglob to have it include dotfiles (other than . and ..) in * (but .* would still include the two).
    – ilkkachu
    Jan 22 at 9:08
  • foo/ isn't the same as foo/. though, at least wrt. mv. On Linux (GNU), mv foo/. bar gives that "Device or resource busy", while mv foo/ bar works.
    – ilkkachu
    Jan 22 at 9:09
  • if foo/ works, someone is stripping the trailing slash, probably mv. YMMV. It will work as a target, but not a source. And all of this is different with rsync as someone already mentioned I think.
    – user10489
    Jan 22 at 13:48
  • if I try it with Perl, both rename("foo/", "bar") and rename("foo", "bar") (as given in Perl and shown by strace) give ENOTEMPTY, unless bar is empty, in which case it replaces bar with foo. On the other hand, rename("foo/.", "bar") gives EBUSY. mv does change the args in that mv foo/ bar calls rename("foo/", "bar/foo").
    – ilkkachu
    Jan 22 at 16:26
  • unsurprisingly mv foo/ bar and mv foo bar/ do the same thing. strace mv foo/ bar | grep rename gives * renameat2(AT_FDCWD, "foo/", AT_FDCWD, "bar", RENAME_NOREPLACE) = -1 EEXIST (File exists) * renameat2(AT_FDCWD, "foo/", AT_FDCWD, "bar/foo", RENAME_NOREPLACE) = 0
    – user10489
    Jan 22 at 17:33

You must log in to answer this question.

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