rekurencyjny mkdir


305

Czy istnieje przeoczone przeze mnie polecenie linux, które umożliwia zrobienie czegoś w stylu: (pseudo)

$ mkdir -R foo/bar/zoo/andsoforth

A może nie ma innej alternatywy niż utworzenie katalogów pojedynczo?



1
zabawne, patrzyłem na tę stronę, ale całkowicie przeoczyłem „rodzica”, ponieważ myślałem o nich jak o dzieciach (od lewej do prawej).

18
Protip: W niektórych muszlach możesz nawet zrobić mkdir -p foo/{bar,baz}/zoo/andsoforth. Bardzo przydatne!
Aaron Copley,

1
Osobiście przeoczyłem również „rodzic” na stronie podręcznika, ponieważ wydaje mi się, że flaga powinna być „-r” dla „rekurencyjnego” - albo przynajmniej powinien istnieć alias dla tego, ponieważ mkdirma tylko 6 udokumentowane flagi ogółem. Do diabła, myślę, że polecenie powinno domyślnie tworzyć katalogi rekurencyjnie, a jeśli nie chcesz tego, musisz to wyraźnie określić.
jbowman

Odpowiedzi:


511
$ mkdir -p foo/bar/zoo/andsoforth

92
Do twojej wiadomości -p oznacza „rodzice”
carl crott

14
Mogliby zamiast tego zrobić -r, jak każde inne polecenie, nie można zapamiętać określonych parametrów dla każdego polecenia linux
Vedmant

2
Ale mkdir -pnie jest wieloplatformowy, nie działa w każdej powłoce
Роман Коптев 17.04.16

9
@ РоманКоптев, mkdir -pjest określony w POSIX , który jest najbliższy temu, aby być w pełni przenośnym. Czego można się spodziewać po skrypcie powłoki?
Wildcard

5
@StephanBijzitter Tak, to jest unix.se, nie unixandwindows.se. :)
EEAA

16

Korzystaniemkdir -p jest prostym sposobem dla większości współczesnych systemów operacyjnych:

mkdir -p foo/bar/zoo/andsoforth

Jednak mkdir -pnie jest zalecane w wielu instrukcjach. Przeczytaj dokumentację GNU makei autoconfproblemy 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 ( cmakelub ) (i ewentualnego przetwarzania wstępnego)autoconfM4

Możesz także użyć install-shskryptu z -dopcją:

install-sh -d foo/bar/zoo/andsoforth

Ten skrypt jest używany przez autoconfi automakeproject. Myślę, że to musi być najbezpieczniejsze rozwiązanie.

W tym czasie szukałem rozwiązania międzyplatformowego dla standardu /bin/shbez 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 -pdla mkdir.

seddirnamedo 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 1na, test -d "$1" || { mkdir "$1" || return 1; }ponieważ mkdirkoń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 aaanie istnieje, poprzednia wersja tworzy, aaaa 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ń.


4
„mkdir -p” jest zdefiniowany przez posix. Jakie warianty unixowe lub podobne do unixa go nie obsługują? (i nie powinna to być wbudowana powłoka, ale chyba nie ma żadnego powodu, dla którego nie mogłaby być). pubs.opengroup.org/onlinepubs/9699919799/utilities/mkdir.html
Tim B

5
Niektóre informacje na tej stronie mają zaledwie 15 lat. Niektóre są starsze.
Thomas Dickey,

7
Systemy, które nie byłyby obsługiwane, mkdir -pbyłyby zbyt stare (a mówimy co najmniej kilka dekad), aby mieć printfnarzędzie lub wsparcie --do oznaczenia końca opcji.
Stéphane Chazelas,

2
Podałeś cdirnamezłą odpowiedź foo/bar//lub nazwy katalogów zawierające znaki nowego wiersza lub nieprawidłowe znaki w bieżącym języku.
Stéphane Chazelas 18.04.16

2
printfjest bezpieczny w systemach POSIX. Obsługa systemów POSIX mkdir -p. mkdir -pjest określany przez POSIX od dziesięcioleci. --zaczął być szeroko rozpowszechniony w systemach AT&T, zaczynając od SysIII we wczesnych latach 80-tych. printfpo raz pierwszy pojawił się jako kshwbudowany, który uważam i został określony przez POSIX później niż mkdir -p. Niektóre powłoki POSIX (takie jak oparte na pdksh lub yash) wciąż nie mają printfwbudowanych.
Stéphane Chazelas,

0

Opcja -pw komendzie mkdirsprawia p katalogów Arent , ile potrzeba (nie błąd, jeśli istnieje):

mkdir -p foo/bar/zoo/andsoforth

Innym sposobem jest na przykład użycie &&(błąd, jeśli określony folder istnieje):

mkdir foo && mkdir foo/bar && mkdir foo/bar/zoo && mkdir foo/bar/zoo/andsoforth

Operator łańcuchowy &&służy do łączenia ze sobą poleceń, dzięki czemu następne polecenie jest uruchamiane tylko wtedy, gdy poprzednie polecenie zakończyło się bez błędów.

Oczywiście pierwszy sposób jest lepszy.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.