Перезаписать существующий каталог?

11

У меня есть имя каталога, fooрасположенного в ~/Desktop. Предположим, я хочу создать каталог из терминала с тем же именем и в том же месте. Когда я пытался mkdirэто выдало ошибку:

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

Это имеет смысл, но я хочу заменить, fooесли существует. Я просмотрел, man mkdirно нет никакой возможности сделать это.

Так как же перезаписать fooкаталог?

Почему нет mkdirвозможности сделать это?

Nux
источник
Заменить fooкак удалить все содержимое этого? mkdirимеет -pпараметр, который игнорирует, если каталог существует.
Муру
4
Итак, вы хотите команду, которая удалит все файлы в каталоге, когда вы случайно создадите новый каталог с тем же именем? И вы удивляетесь, почему это не вариант? Это шутка?
Марти Фрид
downvoters просто уточнить, почему это, я прошу об одной команде, которая удаляет существующий каталог
nux
1
@nux для меня вопрос не имеет смысла ... объясните, почему вы хотите удалить и воссоздать каталог. У нас есть команды для всего, что вам нужно сделать с каталогом. mkdir не нуждается в опции для удаления / воссоздания.
Rinzwind
1
Это преступление здесь, если я задаю логический вопрос!
NUX

Ответы:

21

Если ваша цель - выполнить однострочную команду, которая:

  • Удаляет и воссоздает каталог, ~/Desktop/fooесли он уже существует.
  • Просто создает каталог, ~/Desktop/fooесли он еще не существует.

Тогда вы можете использовать:

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

; эквивалентно новой строке, но позволяет выполнять несколько команд в одной строке (т. е. как «одна команда»).

  • Если удаляемый каталог может содержать файлы только для чтения, вам понадобится -fфлаг, чтобы удалить их без интерактивного запроса пользователя. Это нормально, но я рекомендую быть особенно осторожным rm -rf .... Смотрите man rmподробности.
  • Вам нужна rmкоманда , чтобы закончить перед mkdirвыполнением команды; это причина, чтобы использовать ;вместо &. (Предыдущая команда &выполняется в фоновом режиме асинхронно.)
  • Вам нужно mkdirвыполнить rmкоманду, когда команда будет выполнена успешно; это причина, чтобы использовать ;вместо ||.
  • Вам нужно, чтобы mkdirкоманда запускалась при rmсбое (обычно сбой будет означать, что каталог еще не существует); это причина, чтобы использовать ;вместо &&.
  • Команда rmможет завершиться ошибкой, даже если каталог уже существует, и в этом случае mkdirкоманда также не будет выполнена, но сообщения об ошибках будут иметь смысл, и, вероятно, нет необходимости добавлять промежуточный шаг, проверяющий fooсуществование, прежде чем пытаться его создать.

См 3.2.3 Списки команд в Bash Reference Manual для получения дополнительной информации и разъяснений о ;, &, ||и &&операторов.

Как и предполагал Муруразработал Ринзвинд ), я рекомендую вам посмотреть,rsync будет ли оно соответствовать вашим потребностям в резервном копировании. На странице документации по rsync есть несколько дополнительных полезных руководств , а также это руководство по Ubuntu rsync .

почему у mkdir нет этой опции?

mkdirсоздает каталоги («mk» означает «make» ). Для него также рекурсивно удалять каталоги и все файлы в них было бы плохо, потому что это нарушило бы принцип наименьшего удивления таким образом, что могло бы привести к потере данных.

rmdirдаже не удаляет каталоги, в которых есть (не каталоги) файлы. rmимеет -rопцию, которая имеет смысл, так rmкак ожидается, что файлы будут удалены (это ее цель, поэтому внутренняя опасность интуитивно понятна, и пользователи обычно знают, что нужно соблюдать осторожность при выполнении rmкоманд).

Элия ​​Каган
источник
+1 отлично. Этот ответ выходит за рамки объяснения синтаксиса, что-то, что я хотел бы быть более глубоким на сайтах стека обмена. В этом ответе много золотых самородков.
Говинд Рай
7

Нет, нет единой команды, чтобы делать то, что вы просите.

Почему?

Это философия Unix: пишите программы, которые делают одно и делают это хорошо. Напишите программы для совместной работы. 1

В этом случае, как mkdirи rmкоманды делать то , что вам требуется, и хорошо работают вместе, так rm -rбудет удалить каталог, так что последующее mkdirсоздаст каталог.

1 Искусство программирования Unix , Эрик С. Рэймонд, сам цитирует Дуга Макилроя.

Мур
источник
пока это хороший ответ, я буду искать его
nux
3

Команда для удаления каталога есть rm. Итак, вам нужно 2 команды.

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

Как показано в комментариях, вы можете связать их цепочкой ;(= сделать оба, даже если 1-й сбой) или &&(= только mkdir, если не сбой rm).

Это -rдля удаления dirs. 1-я команда также удаляет ВСЕ содержимое каталога. Если это НЕ ваше намерение, то rm и mkdir - это не то, что вы ищете: разрешения chmodи chown.

почему у mkdir нет этой опции?

Неоднозначность. mkdirзначит сделать каталог. Не удаляйте и делайте каталог. А поскольку rmкоманда предназначена для удаления содержимого, нет необходимости rmdirиметь возможность удалять каталог.

Rinzwind
источник
я знаю это, но я имею в виду одну команду, вы можете просмотреть мое редактирование, я изменяю его
nux
Сначала объясните, почему вам нужно пересоздать каталог. Это не имеет смысла для меня.
Rinzwind
моя потребность имеет смысл, мне просто интересно, как? это имеет смысл для меня :)
NUX
@nux нет, это не так. И сопровождающий mkdir также не понимает, почему;) То, что вы хотите, бесполезно и не имеет смысла.
Rinzwind
хорошо, если вы хотите знать, я делаю скрипт для резервного копирования в новый каталог с тем же именем foo и позволяет заменить его, если существует, чтобы уменьшить пространство
nux
1

Чтобы сделать это самым чистым способом, я использую это:

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 
}

И использовать это:

create_clean_directory <dir_name>

Это гарантирует, что вы пытаетесь удалить каталог, а не файл:

  1. -dПроверьте, существует ли каталог с таким именем. если так, удалите это.

  2. -fУбедитесь, что файл с таким именем не существует. если это так, распечатайте сообщение об ошибке и выйдите.

  3. Создайте новый каталог и повторите эхо, или, если не удалось, эхо не удалось.

Реа Хаас
источник