POSIXly, używałbyś pax
w trybie odczytu i zapisu z -l
opcją:
pax -rwlpe -s /A/B/ dirA .
( -pe
Zachowuje wszystkie możliwe atrybuty plików (w tym przypadku jedynie katalogi), które są skopiowane, jak GNU cp
„s -a
robi).
Teraz, chociaż standardowe , to polecenie niekoniecznie jest bardzo przenośne .
Po pierwsze, wiele systemów opartych na GNU / Linux nie zawiera pax
domyślnie (chociaż nie jest to opcjonalne narzędzie POSIX).
Następnie szereg błędów i niezgodności z kilkoma implementacjami powoduje szereg problemów z tym kodem.
- z powodu błędu Solaris 10
pax
(przynajmniej) nie działa, gdy jest używany -rwl
w połączeniu z -s
. Z jakiegoś powodu wydaje się, że stosuje podstawienie zarówno do oryginalnej, jak i skopiowanej ścieżki. Tak więc powyżej spróbowałby zrobić coś link("dirB/file", "dirB/file")
zamiast link("dirA/file", "dirB/file")
.
- na FreeBSD
pax
nie tworzy twardych dowiązań dla plików typu dowiązanie symboliczne (zachowanie dozwolone przez POSIX). Nie tylko to, ale również stosuje się substytucję do celów dowiązania (zachowanie nie dozwolonych przez POSIX). Tak na przykład, jeśli istnieje foo -> AA
dowiązanie w dirA
, stanie foo -> BA
się dirB
.
Ponadto, jeśli chcesz zrobić to samo, ale z dowolnych ścieżek plik, którego zawartość jest przechowywana w $src
i $dst
ważne jest, aby uświadomić sobie, że pax -rwl -- "$src" "$dst"
tworzy pełną strukturę katalogów $src
wewnętrznej $dst
(który musi istnieć i być katalogiem). Na przykład, jeśli $src
jest foo/bar
, to $dst/foo/bar
jest tworzone.
Jeśli zamiast tego chcesz $dst
być kopią $src
, najłatwiej jest to zrobić:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && pax -rwlpe . "$absolute_dst")
(co obejdzie również większość wyżej wymienionych problemów, ale zawiedzie, jeśli bezwzględna ścieżka $dst
końca kończy się na znakach nowej linii).
Teraz to nie pomoże w systemach GNU / Linux, gdzie nie ma pax
.
Warto zauważyć, że pax
został stworzony przez POSIX w celu scalenia funkcji poleceń tar
i cpio
.
cpio
jest historycznym poleceniem uniksowym (z 1977 r.) w przeciwieństwie do wynalazku POSIX, a także implementacją GNU (nie pax
jedną). Tak więc, mimo że nie jest to już standardowe polecenie (choć było w SUSv2), wciąż jest bardzo powszechne i istnieje podstawowy zestaw funkcji, na których zwykle można polegać.
Odpowiednikiem pax -rwl
byłoby cpio -pl
. Jednak:
cpio
pobiera listę plików wejściowych na stdin w przeciwieństwie do argumentów (znak nowej linii, co oznacza, że nazwy plików ze znakami nowej linii nie są obsługiwane)
- Wszystkie pliki muszą zostać określone (zazwyczaj podajesz dane wyjściowe
find
( find
i cpio
zostały opracowane wspólnie przez te same osoby)).
- metadane nie są zachowywane (niektóre
cpio
implementacje mają opcje zachowania niektórych, ale nic przenośnego).
Więc z cpio
:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && find . | cpio -pl "$absolute_dst")
pax
we FreeBSD,cp -a
nie łączy dowiązań symbolicznych.