Overwrite an existing directory?

76,911

Solution 1

If your goal is to execute a one-line command that:

  • Removes and recreates the directory ~/Desktop/foo if it already exists.
  • Just creates the directory ~/Desktop/foo if it does not already exist.

Then you can use:

rm -r ~/Desktop/foo; mkdir ~/Desktop/foo

; is equivalent to a newline, but it lets you execute multiple commands on a single line (i.e., as a "single command").

  • If the directory you're removing may contain readonly files, you'll need the -f flag to remove them without prompting the user interactively. This is okay, but I do recommend being especially careful with rm -rf .... See man rm for details.
  • You need the rm command to finish before the mkdir command executes; this is the reason to use ; instead of &. (A command preceding & runs asynchronously in the background.)
  • You need the mkdir command to run when the rm command succeeds; this is the reason to use ; instead of ||.
  • You need the mkdir command to run when the rm command fails (usually failure will mean the directory didn't already exist); this is the reason to use ; instead of &&.
  • The rm command might fail even when the directory already existed, in which case the mkdir command will fail also, but the error messages will make sense and there's probably no need to add a middle step checking for foo's existence before trying to create it.

See 3.2.3 Lists of Commands in the Bash Reference Manual for more information and explanation about the ;, &, ||, and && operators.

As muru suggested (and Rinzwind elaborated), I do recommend you look into rsync to see if it will meet your backup needs. There are some additional useful guides on the rsync documentation page, as well as this Ubuntu rsync guide.

why mkdir doesn't has this option ?

mkdir creates directories (the "mk" stands for "make"). For it also to recursively delete directories and all the files in them would be bad, because it would violate the principle of least astonishment in a way that would likely lead to data loss.

rmdir doesn't even remove directories that have any (non-directory) files in them. rm has an -r option, which makes sense since rm is expected to remove files (that is its purpose, thus the inherent danger is intuitive and users typically know to be careful when running rm commands).

Solution 2

No, there is no single command to do what you are asking.

Why?

This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together.1

In this instance, the mkdir and rm commands do what you require, and work well together, since rm -r will delete the directory as well, so a subsequent mkdir will create the directory.

1The Art of Unix Programming, Eric S. Raymond, itself quoting Doug McIlroy.

Solution 3

The command to remove a directory is rm. So you need 2 commands.

rm -r ~/Desktop/foo/
mkdir ~/Desktop/foo/

As shown in comments you can chain them with ; (= do both even if 1st fails) or && (= only mkdir when the rm does not fail).

The -r is for removing dirs. The 1st command also removes ALL contents of the directory. If that is NOT your intention both rm and mkdir are not what you are looking for: permissions are chmod and chown.

why mkdir doesn't has this option ?

Ambiguity. mkdir means make directory. Not remove and make directory. And since the rm command is for deleting stuff there is no need for rmdir to be able to remove a directory.

Solution 4

To do that in the cleanest way I use this:

create_clean_directory(){
    dir_name=$1
    if [ -d "$dir_name" ]; then
        echo "Removing $dir_name"
        rm -rf "$dir_name"
    elif [ -f "$dir_name" ]; then
        echo "File with this name already exists, not a directory."
        exit
    fi
    if mkdir "$dir_name"; then
        echo "Clean directory created: $dir_name"
        return 0
    else
        echo "Creating directory failed: $dir_name"
        return 1
    fi 
}

And to use it:

create_clean_directory <dir_name>

This makes sure that what you are trying to remove is a directory and not a file:

  1. -d Check if a directory with that name already exists. if so, delete it.

  2. -f Check that no file with this name exists. if so, print error message and exit.

  3. Create the new directory and echo success, or if failed, echo failed.

Share:
76,911

Related videos on Youtube

nux
Author by

nux

The Quieter you are , the more you are able to hear . "Once you stop learning, you start dying". -Albert Einstein Started learning Python . I am from Lebanon .

Updated on September 18, 2022

Comments

  • nux
    nux almost 2 years

    I have a directory name foo located in ~/Desktop. Suppose I want to create a directory from a terminal with same name and in the same location. When I tried mkdir it gave an error:

    mkdir: cannot create directory `/home/nux/Desktop/foo': File exists
    

    Thats makes sense, but I want to replace foo if exists. I looked through man mkdir but there isn't any option that do that.

    So how to overwrite foo directory?

    Why doesn't mkdir have an option to do this?

    • muru
      muru almost 10 years
      Replace foo as in delete all contents of it? mkdir has a -p option which ignores if the directory exists.
    • Deepak Verma
      Deepak Verma almost 10 years
      So, you want a command that will delete all the files in a directory when you accidentally create a new directory with the same name? And you wonder why it's not any option? Is this a joke?
    • nux
      nux almost 10 years
      downvoters just clarify why that , am asking about one command that delete an existing directory
    • Rinzwind
      Rinzwind almost 10 years
      @nux to me the question makes no sense ... explain why you ever want to delete and recreate a directory. We have commands for anything you need to do to the directory. mkdir does not need a option to remove/recreate.
    • nux
      nux almost 10 years
      is it a crime here if am asking a logic question !!
    • Gremlin
      Gremlin over 9 years
      Do you need to delete everything inside the directory? If not, and you just want to not have the error, mkdir -p is the option for you.
  • nux
    nux almost 10 years
    i know that , but i mean one command , you can view my edit i change it
  • Rinzwind
    Rinzwind almost 10 years
    1st explain why you need to recreate the directory. That makes NO sense to me.
  • nux
    nux almost 10 years
    is my need make sense , i just wonder how ? it make sense for me :)
  • Rinzwind
    Rinzwind almost 10 years
    @nux no it does not. And neither does the maintainer of mkdir understand why ;) What you want is useless and has no merit.
  • nux
    nux almost 10 years
    ok if you want to know am making a script to make backup in a new directory with the same name of foo and allows replace it if exist to reduce space
  • nux
    nux almost 10 years
    foo contain backup files
  • muru
    muru almost 10 years
    @nux You should be using rsync for that. No need to reinvent the wheel.
  • nux
    nux almost 10 years
    please understand my question , just need to know if there is a command that do that. @muru i know about rsync
  • nux
    nux almost 10 years
    for now , thats a good answer , i will search for that
  • Rinzwind
    Rinzwind almost 10 years
    @nux backup files... you need to research "rsync" not mkdir. rsync has options for what you explained in comments.
  • Govind Rai
    Govind Rai over 7 years
    +1 excellent. This answer goes above and beyond in explaining the syntax, something I wish was more profound on stackexchange sites. There are a lot of golden nuggets in this answer.