Korzystaniemkdir -p
jest prostym sposobem dla większości współczesnych systemów operacyjnych:
mkdir -p foo/bar/zoo/andsoforth
Jednak mkdir -p
nie jest zalecane w wielu instrukcjach. Przeczytaj dokumentację GNU make
i autoconf
problemy z używaniem mkdir -p
:
Wieloplatformowe systemy instalacyjne i konfiguracyjne mają własne bezpieczne alternatywymkdir -p
.
CMrób użyć w wierszu poleceń powłoki:
cmake -E make_directory foo/bar/zoo/andsoforth
Autoconf do użycia w skrypcie z przetwarzaniem wstępnym:
AS_MKDIR_P(foo/bar/zoo/andsoforth)
lub:
AC_PROG_MKDIR_P(foo/bar/zoo/andsoforth)
Ale te rozwiązania wymagają zainstalowania narzędzi ( cmake
lub ) (i ewentualnego przetwarzania wstępnego)autoconf
M4
Możesz także użyć install-sh
skryptu z -d
opcją:
install-sh -d foo/bar/zoo/andsoforth
Ten skrypt jest używany przez autoconf
i automake
project. Myślę, że to musi być najbezpieczniejsze rozwiązanie.
W tym czasie szukałem rozwiązania międzyplatformowego dla standardu /bin/sh
bez zależności, ale go nie znalazłem. Dlatego napisałem następny skrypt, który może nie jest idealny, ale myślę, że jest zgodny z większością wymagań międzyplatformowych :
#! /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
}
Tego skryptu można używać w starych systemach, w których nie ma opcji -p
dla mkdir
.
sed
dirname
do kodu dodano wersję wieloplatformową . Działa w sposób podobny do dirname
(poprawne ze ścieżką /
, ścieżki tylko z nazwą podstawową, ścieżki z końcowymi /
, ścieżkami z końcowymi i bez \n
). Ta funkcja nie może działać poprawnie, jeśli ścieżka ma znaki nowej linii lub niektóre nieprawidłowe znaki dla bieżących ustawień narodowych. Zastępuje również dowolną kombinację /
( //
, ///
) pojedynczym/
Zmieniono linię mkdir "$1" || return 1
na, test -d "$1" || { mkdir "$1" || return 1; }
ponieważ mkdir
kończy się z błędem, jeśli ścieżka istnieje, i to sprawdzenie jest potrzebne dla ścieżek zawierających konstrukcje takie jak aaa\.
(jeśli aaa
nie istnieje, poprzednia wersja tworzy, aaa
a następnie próbuje ją utworzyć ponownie).
Ta wersja mkd nie generuje błędu, jeśli ścieżka już istnieje (ale nadal ma możliwość wygenerowania takiego błędu przy równoległym wykonywaniu) i nie może uzyskać kilku katalogów w wierszu poleceń.