Dlaczego niektóre polecenia GNU Coreutils mają taką -T/--no-target-directory
opcję? Wydaje się, że wszystko, co robi, można osiągnąć za pomocą semantyki .
(self dot) w tradycyjnej uniksowej hierarchii katalogów.
Wobec:
cp -rT /this/source dir
Ta -T
opcja zapobiega tworzeniu dir/source
podkatalogu przez kopię . Raczej /this/source
jest identyfikowany z, dir
a zawartość jest odpowiednio mapowana między drzewami. Więc na przykład /this/source/foo.c
chodzi do dir/foo.c
i tak dalej, niż do dir/source/foo.c
.
Ale można to łatwo osiągnąć bez -T
opcji:
cp -r /this/source/. dir # Probably worked fine since dawn of Unix?
Semantycznie, kropka końcowa jest kopiowana jako dziecko dir
, ale oczywiście to „dziecko” już istnieje (więc nie musi być tworzone) i jest w rzeczywistości dir
sobą, więc efekt /this/path
jest identyfikowany z dir
.
Działa dobrze, jeśli bieżącym katalogiem jest cel:
cp -r /this/tree/node/. . # node's children go to current dir
Czy istnieje coś, co można zrobić tylko z -T
które mogą zracjonalizować swoje istnienie? (Poza obsługą systemów operacyjnych, które nie implementują katalogu kropek, uzasadnienie nie zostało wymienione w dokumentacji.)
Czy powyższa sztuczka punktowa nie rozwiązuje tych samych warunków wyścigu, o których mowa w dokumentacji GNU Info -T
?
.
Trik robi pracę podczas kopiowania pliku, nie tylko podczas zmiany nazwy jego basename w tym samym czasie!cp /path/to/file /target/dir/.
Jeśli/target/dir/file
istnieje i jest katalogiem, otrzymasz taką samą diagnostykę! Ale pokazałeś, czego-T
nie da się zrobić bez niego w jednym kroku, bez warunków wyścigu: skopiuj plik i zmień jego nazwę, bez przetaczania go do podkatalogu..
sztuczka, o której mówisz, polega na dołączeniu/.
do źródła .Problem z
cp
/mv
/ln
tak, jak zostały pierwotnie zaprojektowane, polega na tym, że są to dwa polecenia w jednym ( kopiowanie do i kopiowanie do ).to albo kopia A do B, albo kopia A do B ( kopia A do B / A ) w zależności od tego
B
, czy istnieje i jest katalogiem, czy nie (i więcej odmian, jeśli B jest dowiązaniem symbolicznym do katalogu).To źle, ponieważ jest niejednoznaczne. Dlatego implementacje GNU dodały opcje obejścia tego.
niezależnie od tego kopiuje A do B. Jeśli
B
istnieje i jest katalogiem, to się nie powiedzie (chyba że zdasz-r
). W każdym razie nie będziesz miećA
pliku w środku,B
gdy zamierzaszA
zostać skopiowany do B.I:
jest kopia do .
źródło
cp A B
polecenia, nie zrobi tego, co zamierzałeś. A robienie[ -e B ] || [ -L B ] || cp A B
nadal ma warunki wyścigowe, którychcp -Tn A B
nie ma.-T
Może dostarczyć awarię jeśli katalog nieprawidłowo istnieje za to, co powinno być plik docelowy:Oznacza to, że zamiast udanego nieoczekiwanego kopiowania do podkatalogu pojawia się ostrzeżenie i zły stan wyjścia, co może spowodować przerwanie skryptu, a człowiek sprawdza, dlaczego istnieje katalog, w którym nie powinien być jednością.
źródło
Używanie flagi jest również znacznie bardziej przejrzyste i wiąże się z mniejszym ryzykiem niezamierzonych efektów, gdy polecenie jest używane w skrypcie zamiast ręcznie wprowadzone. Łata kropek na ścieżkach w skrypcie może skończyć się wszelkiego rodzaju nieoczekiwanymi psotami.
źródło