У меня есть имя каталога, foo
расположенного в ~/Desktop
. Предположим, я хочу создать каталог из терминала с тем же именем и в том же месте. Когда я попытался, mkdir
он выдал ошибку:
mkdir: cannot create directory `/home/nux/Desktop/foo': File exists
Это имеет смысл, но я хочу заменить, foo
если есть. Я просмотрелman mkdir
но нет возможности сделать это.
Так как же перезаписать foo
каталог?
Почему нет mkdir
возможности сделать это?
решение1
Если ваша цель — выполнить однострочную команду, которая:
- Удаляет и заново создает каталог,
~/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для получения дополнительной информации и объяснений об операторах ;
, &
, ||
и &&
.
КакМуру предложил(иРинзвинд подробно рассказал),Я рекомендую вам рассмотретьrsync
чтобы увидеть, будет ли он соответствовать вашим потребностям в резервном копировании. Есть несколько дополнительных полезных руководств настраница документации rsync, а такжеэто руководство по Ubuntu rsync.
почему у mkdir нет этой опции?
mkdir
создает каталоги ("mk"означает «сделать»). Для него также рекурсивное удаление каталогов и всех файлов в них было бы плохим, потому что это нарушило быпринцип наименьшего удивлениятаким образом, что это с большой вероятностью приведет к потере данных.
rmdir
даже не удаляет каталоги, в которых есть какие-либо файлы (не являющиеся каталогами).rm
имеет -r
опцию, что имеет смысл, поскольку rm
предполагается удаление файлов (это ее цель, поэтому присущая ей опасность интуитивно понятна, и пользователи обычно знают, что при запуске rm
команд следует соблюдать осторожность).
решение2
Нет, не существует единой команды, которая бы сделала то, о чем вы просите.
Почему?
Это философия Unix: Пишите программы, которые делают что-то одно и делают это хорошо. Пишите программы, которые будут работать вместе. 1
В этом случае команды mkdir
и rm
выполняют то, что вам нужно, и хорошо работают вместе, поскольку rm -r
также удаляют каталог, поэтому последующая команда mkdir
создаст каталог.
1Искусство программирования Unix, Эрик С. Рэймонд, цитирующий Дуга Макилроя.
решение3
Команда для удаления каталога — rm
. Итак, вам нужно 2 команды.
rm -r ~/Desktop/foo/
mkdir ~/Desktop/foo/
Как показано в комментариях, вы можете объединить их с помощью ;
(= выполнить обе команды, даже если первая не удалась) или &&
(= только mkdir, когда rm не удалась).
Для -r
удаления каталогов. Первая команда также удаляет ВСЕ содержимое каталога. Если это НЕ ваше намерение, то и rm, и mkdir — не то, что вы ищете: разрешения — это chmod
и chown
.
почему у mkdir нет этой опции?
Неоднозначность. mkdir
означает сделать каталог. Не удалить и сделать каталог. И поскольку rm
команда предназначена для удаления вещей, то нет необходимости rmdir
иметь возможность удалить каталог.
решение4
Чтобы сделать это максимально чисто, я использую следующее:
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>
Это гарантирует, что вы пытаетесь удалить именно каталог, а не файл:
-d
Проверьте, существует ли уже каталог с таким именем. Если да, удалите его.-f
Проверьте, не существует ли файла с таким именем. Если да, выведите сообщение об ошибке и выйдите.Создайте новый каталог и выполните команду echo «Успешно» или, в случае неудачи, команду echo «Не удалось».