Chcę utworzyć „kopię” drzewa katalogów, w którym każdy plik jest dowiązaniem twardym do oryginalnego pliku
Przykład: Mam strukturę katalogów:
dirA/
dirA/file1
dirA/x/
dirA/x/file2
dirA/y/
dirA/y/file3
Oto oczekiwany wynik, „kopia” drzewa katalogów, w którym każdy plik jest dowiązaniem twardym do oryginalnego pliku:
dirB/ # normal directory
dirB/file1 # hardlink to dirA/file1
dirB/x/ # normal directory
dirB/x/file2 # hardlink to dirA/x/file2
dirB/y/ # normal directory
dirB/y/file3 # hardlink to dirA/y/file3
pax
we FreeBSD,cp -a
nie łączy dowiązań symbolicznych.POSIXly, używałbyś
pax
w trybie odczytu i zapisu z-l
opcją:(
-pe
Zachowuje wszystkie możliwe atrybuty plików (w tym przypadku jedynie katalogi), które są skopiowane, jak GNUcp
„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.
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")
zamiastlink("dirA/file", "dirB/file")
.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 istniejefoo -> AA
dowiązanie wdirA
, staniefoo -> 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, żepax -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
jestfoo/bar
, to$dst/foo/bar
jest tworzone.Jeśli zamiast tego chcesz
$dst
być kopią$src
, najłatwiej jest to zrobić:(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
icpio
.cpio
jest historycznym poleceniem uniksowym (z 1977 r.) w przeciwieństwie do wynalazku POSIX, a także implementacją GNU (niepax
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łobycpio -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)find
(find
icpio
zostały opracowane wspólnie przez te same osoby)).cpio
implementacje mają opcje zachowania niektórych, ale nic przenośnego).Więc z
cpio
:źródło
-s /A/B
zastępujeA
sięB
tak, żedirA
staje siędirB
. Jeśli nazwa twojego katalogu źródłowego nie maA
, to skopiuje (link) ją nad sobą. Zobacz także resztę odpowiedzi na potencjalnie lepsze podejścia.Krótka odpowiedź:
źródło
W przypadku, gdy szukasz funkcji kopiowania z hardlinkami, aby tworzyć migawki lub kopie zapasowe (wszystkich lub części) swoich plików
rsnapshot
.źródło
Odpowiedź @ gudmundur-orn jest poprawna, ale jeśli korzystasz z BtrFS w systemie Linux,
cp a --reflink=auto dirA dirB
powinieneś załatwić sprawę , z tą różnicą, że pliki są różne, a zmiana jednego nie zmienia drugiego. Możesz osiągnąć w większości to samo zcp -c
komputerem Mac z APFS (auto
jeśli to niemożliwe, zrobi pełną kopię, nie-c
powiedzie się).Każdy system plików COW powinien być w stanie to zrobić, ale dostawcy nie uzgodnili standardowej opcji wiersza poleceń.
źródło