Linux, jak kopiować, ale nie nadpisywać?

385

Chcę cpkatalogu, ale nie chcę zastępować żadnych istniejących plików, nawet jeśli są one starsze niż skopiowane pliki. Chcę to zrobić całkowicie nieinteraktywnie, ponieważ będzie to część skryptu Crontab Bash. Jakieś pomysły?

mnowotka
źródło

Odpowiedzi:

589

Zrobione ze strony człowieka :

-n, --no-clobber
              do not overwrite an existing file (overrides a previous -i option)

Przykład:

cp -n myoldfile.txt mycopiedfile.txt
hovanessyan
źródło
32
Uwaga: zakończy się to z błędem, jeśli plik istnieje. Aby zakończyć z sukcesem, spróbuj cp -n source.txt destination.txt || true
galenandrew
13
@galenandrew cp -nnie wychodzi z błędem, jeśli plik istnieje w systemie Ubuntu 12.04.
amit
@galenandrew Potwierdzony. Dziękuję Ci. Mój projekt nie budował się w Xcode po dodaniu skryptu uruchamiania do mojego celu.
Ruiz
@AaronFranke wygląda tak.
Boris
93

Rozważ użycie rsync.

rsync -a -v --ignore-existing src dst

Zgodnie z komentarzami rsync -a -v src dstnie jest poprawny, ponieważ zaktualizuje istniejące pliki.

Hans Ginzel
źródło
7
Chcesz dodać --ignore-existingflagę, aby zapobiec zastąpieniu istniejących plików.
Wszyscy pracownicy są niezbędni
7
Kompletne polecenie rsync -a -v --ignore-existing <src> <dst>jest rzeczywiście poprawną odpowiedzią zamiast cp -upowyższej.
Whitebird
Jeśli poprzednia kopia została przerwana i skopiowany został tylko obcięty plik, jestem pewien, że cp -u nie skopiuje go ponownie ... ale uruchomi rsync z opcją --ignore-exist? Prawdopodobnie też nie ... dzięki czemu są idealnie równoważne, prawda?
dagelf
rsync zachowuje sygnaturę czasową pliku, podczas gdy cp wykorzystuje aktualny czas (z mojego doświadczenia)
Stefan Diabo
1
niektóre serwery po prostu nie mają rsync
mebada
51
cp -n

To jest to czego chcesz. Zobacz stronę manuala.

bucko
źródło
@AaronFranke tak, będzie działać rekurencyjnie.
Boris
33

Działa to w RedHat:

false | cp -i source destination 2>/dev/null

Aktualizacja i nie nadpisywanie to coś innego.

Ceving
źródło
4
Co falsetu robi?
Frozen Flame
11
@FrozenFlame Odpowiedzi na -ipytania.
ceving
Oczywiście to polecenie nie będzie działać, jeśli spróbujesz skopiować więcej niż pliki ARG_MAX. Aby obejść ten przypadek, sprawdź ten link .
mginius
2
Oczywiście, to polecenie nie zadziała, jeśli ziemia uderzy w słońce.
Ceving
32

W przypadku osób, które nie mają opcji „n” (jak ja w RedHat), możesz użyć cp -udo zapisania pliku tylko wtedy, gdy źródło jest nowsze niż istniejące (lub nie istnieje).

[edytuj] Jak wspomniano w komentarzach, spowoduje to zastąpienie starszych plików, więc nie jest to dokładnie to, czego chciał OP. Użyj do tego odpowiedzi Cevinga.

Ponury...
źródło
11
OP poprosił, aby nie zastępować istniejących plików, nawet jeśli są one starsze niż skopiowane pliki , więc tak -unaprawdę nie pasuje do celu.
Andrew Lott,
4
Boże, masz absolutną rację. Dziwi mnie, że tak długo zajęło to zauważenie.
Ponury ...
Być może nie o to poprosił OP, ale właśnie tego potrzebowałem do mojej Uberspace (Centos 7). Dzięki!
Thomas Praxl,
Cieszę się, że sześć lat temu mogłem pomóc :-D
Ponury ...
10

Alpine linux: Poniższa odpowiedź dotyczy tylko jednego pliku: w alpine cp -nnie działa (i false | cp -i ...też), więc rozwiązanie działające w moim przypadku, które znalazłem to:

if [ ! -f env.js ]; then cp env.example.js env.js; fi 

W powyższym przykładzie, jeśli env.jsplik nie istnieje, kopiujemy env.example.jsdo env.js.

Kamil Kiełczewski
źródło
1

Niektóre wersje cp nie mają opcji --no-clobber . W tym wypadku:

  echo n | cp -vipr src/* dst
Oktawian
źródło