рекурсивный mkdir
Есть ли команда linux, которую я пропускаю, что позволяет сделать что-то в соответствии с: (Псевдо)
$ mkdir -R foo /bar /zoo /andsoforth
Или нет альтернативы, кроме как создавать каталоги по одному за раз?
4 ответа
Использование mkdir -p
- более простой способ для большинства современных oses:
mkdir -p foo /bar /zoo /andsoforth
Однако, использование mkdir -p
не рекомендуется во многих руководствах. Прочитайте документацию для последних версий gnu make
и autoconf
о проблемах с использованием mkdir -p
:
- http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Limitations-of-Usual-Tools.html#Limitations-of-Usual- Инструменты
- http: //www. gnu.org/savannah-checkouts/gnu/make/manual/html_node/Utilities-in-Makefiles.html
Системы установки и конфигурации кросс-платформы имеют свои безопасные альтернативы для mkdir -p
.
CMake для использования в командной строке оболочки:
cmake -E make_directory foo /bar /zoo /andsoforth
Autoconf для использования в скрипте с предварительной обработкой:
AS_MKDIR_P (Foo /бар /зоопарк /andsoforth)
или
AC_PROG_MKDIR_P (Foo /бар /зоопарк /andsoforth)
Но для этих решений требуются инструменты cmake
или autoconf
(M4
), которые необходимо установить (и возможная предварительная обработка)
Вы также можете использовать скрипт install-sh
с опцией -d
:
install-sh -d foo /bar /zoo /andsoforth
Этот сценарий используется autoconf
и automake
. Я думаю, что это должно быть самым безопасным решением.
В то время я искал кросс-платформенное решение для стандартного /bin /sh
без зависимостей, но не нашел его. Поэтому я написал следующий скрипт, который может быть не идеальным, но я думаю, что он соответствует большинству требований к кросс-платформе :
#! /Бен /ш
cdirname () # альтернатива кросс-платформенной для 'dirname'
{
# $ 1 - путь
test $ # -eq 1 || {echo "Процедура 'cdirname' должна иметь только один параметр. Ошибка сценария."; выход 1; }
эхо "$ 1" | sed -n -e '1p' | sed -e's # //* # /# g '-e's # \ (. \) /$ # \ 1 #' -e '# ^ [^ /] * $ #. #' -e ' s # \ (. \) /[^ /] * $ # \ 1 # '-
}
mkd () # альтернатива кросс-платформенной для 'mkdir -p'
{
# $ 1 - каталог для создания
test $ # -eq 1 || {echo «Функция« mkd »может создать только один каталог (с его родительскими каталогами)."; выход 1; }
test -d "$ 1" & & & возвращение 0
test -d "$ (cdirname" $ 1 ")" || {mkd "$ (cdirname" $ 1 ")" || return 1; }
test -d "$ 1" || {mkdir "$ 1" || return 1; }
возвращение 0
}
Этот скрипт может использоваться для старых систем, где отсутствует опция -p
для mkdir
.
sed
- межплатформенная версия dirname
. Он работает со способом, аналогичным dirname
(исправить с помощью пути /
), только пути с базовым именем, пути с завершающим кодом /
, пути с и без trailing \ n
s). Эта функция не может работать корректно, если путь имеет новые строки или некоторые недопустимые символы для текущей локали. Он также заменяет любую комбинацию /
(//
, ///
) с помощью одного /
Измененная строка mkdir "$ 1" || return 1
в test -d "$ 1" || {mkdir "$ 1" || return 1; }
, потому что mkdir
завершается с ошибкой, если существует путь, и эта проверка необходима для путей, содержащих конструкции типа aaa \.
(if aaa
не существует предыдущей версии создает aaa
, а затем пытается создать его снова).
Эта версия mkd не генерирует ошибку, если путь уже существует (но он все еще имеет возможность генерировать такую ошибку при параллельном выполнении) и не может получить несколько каталогов в командной строке.
Опция -p
в команде mkdir
делает p arent directories по мере необходимости (без ошибок, если они существуют):
mkdir -p foo /bar /zoo /andsoforth
Другим способом является, например, использование & &
(ошибка, если указанная папка существует):
mkdir foo & & & mkdir foo /bar & & mkdir foo /bar /zoo & & & mkdir foo /bar /zoo /andsoforth
Оператор цепочки &
используется для объединения команд вместе, так что следующая команда запускается тогда и только тогда, когда предыдущая команда вышла без ошибок.
Конечно, первый способ лучше.
mkdir foo foo /bar foo /bar /zoo /foo /bar /zoo /andsofort.
Это должно сделать это.