cp vs. cat, aby skopiować plik

12

cp a bi cat a > bjaka jest różnica?

W skrypcie instalacyjnym x86 drzewa źródłowego jądra linuxa ( arch/x86/boot/install.sh) używane są oba:

cat $2 > $4/vmlinuz
cp $3 $4/System.map

Dlaczego nie zachowają tego samego formatu, jeśli jeden jest lepszy od drugiego?

Qian
źródło

Odpowiedzi:

15

Przyszło mi do głowy jeszcze jedno zagadnienie, w którym catvs. cprobi znaczącą różnicę:

Z definicji cat rozszerzy rzadkie pliki, wypełniając luki „prawdziwymi” bajtami zerowymi, podczas gdy co najmniej cp można nakazać zachowanie dziur.

Pliki rzadkie to pliki, w których sekwencje zerowe bajtów zostały zastąpione metadanymi w celu zaoszczędzenia miejsca. Możesz przetestować, tworząc go za pomocą dd i powielić go za pomocą wybranych narzędzi.

  1. Utwórz rzadki plik (wcześniej zmieniając na / tmp, aby uniknąć problemów - patrz uwaga końcowa):

    15> cd /tmp
    16> dd if=/dev/null of=sparsetest bs=512b seek=5 
    0+0 records in 
    0+0 records out 
    0 bytes (0 B) copied, 5.9256e-05 s, 0.0 kB/s
  2. zmień to - nie powinno zająć miejsca.

    17> du -sh sparsetest
    0       sparsetest
  3. skopiuj z cp i sprawdź rozmiar

    18> cp sparsetest sparsecp
    19> du -sh sparsecp
    0       sparsecp
  4. teraz skopiuj go za pomocą kota i sprawdź rozmiar

    20> cat sparsetest > sparsecat
    21> du -sh sparsecat
    1.3M    sparsecat
  5. wypróbuj preferowane narzędzia, aby sprawdzić ich zachowanie

  6. nie zapomnij posprzątać.

Ostatnia uwaga: takie eksperymenty mają nieodłączną szansę na zdobycie sławy u lokalnego administratora systemu, jeśli wykonujesz je na systemie plików, który jest częścią jego planu tworzenia kopii zapasowych lub jest krytyczny dla dobrego funkcjonowania systemu. W zależności od wyboru narzędzia do tworzenia kopii zapasowych może on potrzebować więcej nośników taśmowych, niż kiedykolwiek uważał za możliwe wykonanie kopii zapasowej tego jednego pliku 0-bajtowego, który zostanie rozszerzony do terabajtów zer.

Inne pliki, których nie można skopiować ani za pomocą cat, ani cp, zawierałyby specjalne pliki na urządzeniu itp. Zależy to od implementacji narzędzia do kopiowania, czy jest on w stanie powielić węzeł urządzenia, czy też wesoło skopiowałby jego zawartość.

Tatjana Heuser
źródło
1
Tak cpczyni plik tak jak w oryginale, natomiast cattworzy nowy plik o tej samej treści.
Qian,
Oba narzędzia działają na treści, ale cp (przynajmniej „nowoczesne” implementacje) jest obecnie świadomy niektórych specjalizacji, takich jak dziury (stare implementacje cat wpadną w tę pułapkę). Istnieją również systemy plików, które nie są świadome koncepcji rzadkich plików, na przykład HFS + (MacOS) lub FAT (MSDOS, USB-Sticks itp.), Powodując ich powiększenie do pełnego rozmiaru. Są więc konstelacje, w których cp lub kot nie zrobią różnicy w praktyce.
Tatjana Heuser
Btw, GNU cpma opcję kontrolowania swojego zachowania na rzadkich plikach; jak, z --sparse=neverokreślonym w linii poleceń, cpjest tak wolny jak cat.
oguz ismail
6

Zgodnie z komentarzem Keitha , cpzachowuje pewne uprawnienia i cattworzy nowy plik jak umaskwskazuje. Tak więc $2pozwolenie nie jest zachowane, $4/vmlinuzjest całkiem czyste, a jeśli jakieś dziwne pozwolenie zostanie włączone $3, $4/System.mapzachowa to.

TheoYou
źródło
czy to jest powód, by przypisywać cattrwałość?
Nikhil Mulley
2
Jest catszybszy?
Qian,
4

Oba mają równoważne funkcje w tych dwóch przypadkach, ale cp jest czysto operacją na pliku. „Weź ten plik i zrób jego kopię”.

cat, z drugiej strony, ma na celu zrzucenie zawartości pliku na konsolę. „Weź ten plik i wyświetl go na ekranie”, a następnie niech ninja zaatakuje ekran i przekieruje wyjście w inne miejsce.

cp byłby ogólnie bardziej wydajny, ponieważ nie ma tylko przekierowania, jedynie bezpośrednie kopiowanie bajtów z lokalizacji A do lokalizacji B.

kot byłby read bytes -> output to console -> intercept output -> redirect to new file.


źródło
3
cattak naprawdę nie output to console -> intercept output -> redirect to new file, plik wyjściowy dla cat może być standardowym lub zwykłym plikiem, po prostu wyśle ​​do pliku, o ile dane wejściowe nie są takie same jak dane wyjściowe.
4
catnie ma nic wspólnego z konsolą. Zarówno cati cpodczytać z pliku wejściowego i zapisać do pliku wyjściowego. Z cat, plik wyjściowy jest otwierany przez powłokę, podczas gdy z cp, plik wyjściowy jest otwierany przez cp; nie ma to różnicy w wydajności. cpmoże być szybszy, ale z zupełnie innego powodu: niektóre implementacje cppróbują odgadnąć właściwy rozmiar porcji dla wydajności w zależności od urządzenia źródłowego i docelowego; wdrożenie catnie przeszkadzałoby.
Gilles „SO- przestań być zły”
2

To naprawdę kwestia preferencji, IMHO.

Technicznie nie ma prawdziwej różnicy, chyba że użyjesz polecenia cp z przełącznikiem -p, aby zachować własność / grupę plików. W przeciwnym razie funkcjonalnie jest to samo. Odpowiedź Marca jest jednak o wiele bardziej szczegółowa i dokładna.

Kręgle
źródło
3
cpbez -pzachowuje niektóre uprawnienia. Na przykład, jeśli plik źródłowy jest wykonywalny, cpspowoduje, że plik docelowy będzie wykonywalny, ale catnie.
Keith Thompson
Słuszna uwaga! Więc vmlinuznie będzie wykonywalny, czy $2jest.