Використанняmkdir -p - це простий спосіб для більшості сучасних ОС:
mkdir -p foo/bar/zoo/andsoforth
Однак mkdir -pце не рекомендується в багатьох посібниках. Прочитайте документацію про GNU makeта autoconfпро проблеми з використанням mkdir -p:
Системи встановлення та налаштування крос-платформ мають свої власні безпечні альтернативиmkdir -p .
CMake для використання в командному рядку оболонки:
cmake -E make_directory foo/bar/zoo/andsoforth
Autoconf для використання в сценарії з попередньою обробкою:
AS_MKDIR_P(foo/bar/zoo/andsoforth)
або:
AC_PROG_MKDIR_P(foo/bar/zoo/andsoforth)
Але ці рішення вимагають встановлення cmakeабо autoconf( M4) інструментів (та можливої попередньої обробки)
Ви також можете використовувати install-shсценарій з -dопцією:
install-sh -d foo/bar/zoo/andsoforth
Цей сценарій використовується autoconfі automakeпроектується. Я думаю, що це має бути найбезпечнішим рішенням.
У той час я шукав крос-платформне рішення для стандарту /bin/shбез залежностей, але не знайшов. Тому я написав наступний сценарій, який може бути не ідеальним, але я думаю, що він відповідає більшості вимог крос-платформи :
#! /bin/sh
cdirname() # cross platform alternative for 'dirname'
{
# $1 - path
test $# -eq 1 || { echo "Procedure 'cdirname' must have only one parameter. Scripting error."; exit 1; }
echo "$1" | sed -n -e '1p' | sed -e 's#//*#/#g' -e 's#\(.\)/$#\1#' -e 's#^[^/]*$#.#' -e 's#\(.\)/[^/]*$#\1#' -
}
mkd() # cross platform alternative for 'mkdir -p'
{
# $1 - directory to create
test $# -eq 1 || { echo "Function 'mkd' can create only one directory (with it's parent directories)."; exit 1; }
test -d "$1" && return 0
test -d "$(cdirname "$1")" || { mkd "$(cdirname "$1")" || return 1; }
test -d "$1" || { mkdir "$1" || return 1; }
return 0
}
Цей скрипт можна використовувати для старих систем, де параметр -pдля mkdirвідсутній.
seddirnameдо коду була додана версія міжплатформованої крос-платформи . Він працює з аналогічним способом dirname(правильний з контуром /, контури лише з базовою назвою, контури з трейлінгами /, контури з трейлінгами та без них \n). Ця функція не може працювати правильно, якщо у шляху є нові рядки або деякі недійсні символи для поточного локалу. Він також замінює будь-яку комбінацію /( //, ///) з одинарною/
Змінено рядок mkdir "$1" || return 1на test -d "$1" || { mkdir "$1" || return 1; }тому, що mkdirзакінчується помилкою, якщо існує шлях, і ця перевірка потрібна для шляхів, що містять конструкції типу aaa\.(Якщо aaaне існує попередньої версії, aaaа потім намагається створити її знову).
Ця версія mkd не генерує помилку, якщо шлях вже існує (але він все ще має можливість генерувати таку помилку при паралельному виконанні) і не може отримати декілька каталогів у командному рядку.