Jeśli chcę file2
dopasować zawartość do zawartości file1
, oczywiście mógłbym po prostu uruchomić cp file1 file2
.
Jednakże, jeśli chcę zachować wszystko o file2
wyjątkiem tej Contents-właściciela, uprawnień, rozszerzonych atrybutów, ACL, twardych linków, etc., etc., to ja nie chce uruchomić cp
. * W tym przypadku po prostu chcę plop zawartość file1
w file2
.
Wygląda na to, że:
< file1 > file2
Ale to nie działa. file2
jest obcięty do zera i nie jest napisany do. Jednak,
cat < file1 > file2
wykonuje pracę.
Zaskoczyło mnie, że pierwsza wersja nie działa.
Czy druga wersja to UUOC? Czy można to zrobić bez wywoływania polecenia, używając jedynie przekierowań?
Uwaga: Zdaję sobie sprawę, że UUOC jest bardziej pedantycznym punktem niż prawdziwy anty-wzór.
* Jak odkrył tniles09 , w rzeczywistości cp
będzie działać w tym przypadku.
źródło
< file1 > file2
czy chcesz, co chcesz, zależy od powłoki.<
...file1
nie istnieje lub jest nieczytelny, i otwórz go<
przed>
otwarciem wyjścia, a następnie zastanów się, co się stanie, gdy pozwoliszcat
spróbować go otworzyć.cat
(domyślnie), zasadniczo uruchamiając drugie polecenie. Zobacz odpowiedź Stéphane'a Chazelasa poniżej, aby uzyskać więcej informacji na ten temat niż mieści się w komentarzu.Odpowiedzi:
cat < file1 > file2
nie jest UUOC. Klasycznie<
i>
wykonuj przekierowania, które odpowiadają duplikacjom deskryptorów plików na poziomie systemu. Duplikacje deskryptorów plików same w sobie nic nie robią (no cóż,>
przekierowania otwierają sięO_TRUNC
, aby być dokładnym, przekierowania wyjściowe powodują obcięcie pliku wyjściowego). Nie daj się<
>
zwieść symbolom. Przekierowania nie przenoszą danych - przypisują deskryptory plików do innych deskryptorów plików.W takim przypadku otwierasz
file1
i przypisujesz ten deskryptor pliku do deskryptora pliku0
(<file1
==0<file1
)file2
oraz przypisujesz ten deskryptor pliku do deskryptora pliku1
(>file2
==1>file2
).Teraz, gdy masz dwa deskryptory plików, potrzebujesz procesu przeszukiwania danych między nimi - i po to
cat
jest.źródło
Nie jest tak, ponieważ jak zauważyli inni, dane zachowanie zależy od powłoki. Jak zauważyliście (OP), jest to trochę pedantyczne , a może nawet humorystyczne? , rodzaj tematu.
Jednak w systemach GNU, początkowy przesłanka ma innego rozwiązania dostępne:
cp --no-preserve=all file1 file2
. Wypróbuj to, myślę, że zaspokoi opisaną sytuację (np. Modyfikując zawartość,file2
ale nie modyfikując jej atrybutów).Przykład :
UPDATE Faktycznie, Właśnie zauważyłem, że mój system na
cp
sam zdaje się zachować atrybuty chyba-a
albo-p
są określone. Używam powłoki bash i coreutils GNU. Myślę, że codziennie uczysz się czegoś nowego ...Wyniki testu (według Wildcard), w tym twardy link i różne uprawnienia:
źródło
W
zsh
powłoce, w której< file1 > file2
działa, powłoka jest wywoływanacat
.W przypadku wiersza poleceń, który składa się tylko z przekierowań, bez polecenia ani przypisań,
zsh
wywołuje$NULLCMD
(cat
domyślnie), chyba że jedynym przekierowaniem jest to,<
w którym zamiast tego wywoływane jest$READNULLCMD
(pager
domyślnie). (tozsh
znaczy, chyba że jest wsh
lubcsh
emulacji, w którym to przypadku zachowuje się jak emulowane powłoki).Więc:
jest w rzeczywistości taki sam jak
i
jest taki sam jak
źródło
nie działa, ponieważ nie ma tam żadnego polecenia; bez procesu. Powłoka otwiera / tworzy pliki i porządkuje przekierowania (co oznacza, że deskryptory plików odnoszące się do tych plików są umieszczane jako 0 i 1: standardowe wejście i standardowe wyjście). Ale nie ma nic do zrobienia, aby wykonać pętlę do odczytu ze standardowego wejścia i zapisu na standardowe wyjście.
zsh
sprawia, że działa to poprzez zastąpienie polecenia konfigurowanego przez użytkownika w tym przypadku „polecenia zerowego”. Polecenie nie jest widoczne w wierszu polecenia, ale nadal tam jest. Proces jest dla niego tworzony i działa w ten sam sposób.NULLCMD
jestcat
domyślnie, więc< from > to
właściwie oznaczacat < from > to
inzsh
, chyba żeNULLCMD
jest ustawiony na coś innego; jest to polecenie „ukrytego kota”.„Bezużyteczne użycie cat” występuje, gdy
cat
jest używane jako pośrednik do odczytu z pliku i przekazania danych do innego procesu, którego deskryptor pliku można po prostu podłączyć do oryginalnego pliku.Jeśli
cat
można usunąć z sytuacji, tak że pozostałe polecenia mogą nadal wykonywać to samo zadanie, jest to bezużyteczne. Jeśli nie można go usunąć, to nie jest bezużyteczny.To,
cat
co można wymienić, to nie to samo. Na przykład zamiastcat > file
możemy użyćvi file
do utworzenia pliku. Nie liczy się to jako usunięciecat
, podczas gdy wszystko, co pozostało, do wykonania tego samego zadania.Jeśli
cat
jest to jedyne polecenie w potoku, to oczywiście nie można go usunąć; żadne przegrupowanie tego, co pozostanie, nie wykona równoważnej pracy.Niektórzy skrypty powłoki używają,
cat
ponieważ uważają, że pozwala im to przenieść operand wejściowy bliżej lewej strony wiersza poleceń. Przekierowania mogą być jednak w dowolnym miejscu wiersza poleceń:źródło
f -
do tar.tar xf -
jest po prostutar x
.cat
jest zaangażowany w tworzenie pliku? Odpowiedź wyraźnie mówi, że powłoka to robi. Z jakim problemem> file
masz na myśli? Często używam go osobno do obcięcia istniejącego pliku do zera lub zapewnienia, że taki istnieje. To pytanie dotyczy tego, dlaczego< from > to
tak nie działacat < from > to
, a UUoC, a nie „proszę podać powody, dla którychcat
nie jest dobrym substytutemcp
”.tar
to archiwizator taśm . Wieletar
implementacji nadal domyślnie działa z pierwszym urządzeniem taśmowym.< file1 > file2
Wydaje się być zależny od powłoki, działa na Zsh, a nie na bash.edycja: usunięte fałszywe oświadczenie
źródło
cp -a
zachowuje atrybuty pliku 1 i zastępuje atrybuty pliku 2. Przeciwnie do pożądanego zachowania. Nie mogę nawet powiedzieć, patrząc na stronę podręcznika, co się stanie z twardymi linkami, ale myślę, że można bezpiecznie powiedzieć, że twarde linki pliku 2 nie zostaną zachowane.Oprócz wszystkich dobrych odpowiedzi, można uniknąć UUOC przez symulowanie
cat
:Te polecenia nie kopiują metadanych pliku, jak zwykły
cp
.źródło
cat
. Tutaj potrzebujesz polecenia, aby przesunąć dane między dwoma deskryptorami plików icat
jest jednym z najlepszych do tego. Zobacz także,pv
który mógłby być użytysplice()
w Linuksie dla systemu Fifos (choć nie działa takfadvise(POSIX_FADV_SEQUENTIAL)
jak GNUcat
).dd
Polecenia dla plików binarnych wydaje się dobre ... czy będziecat
działać tak samo dobrze dla plików binarnych?cat
działa również dla plików binarnych (Unix generalnie nie rozróżnia; jednak niektóre narzędzia działają konkretnie linia po linii, takie jak awk, grep, wc, ... POSIX określa również minimalną największą długość linii, więc teoretycznie narzędzie zorientowane na linie może odmówić radzenia sobie z nadmiernie dużymi liniami.)sed '' < file1 > file2
;-)Jeśli to działa, nie naprawiaj tego.
użyłbym
i nie przejmuj się komputerem semantyki.
źródło