scp sin reemplazar los archivos existentes en el destino

158

¿Cómo copio un directorio completo en un directorio con el mismo nombre sin reemplazar el contenido en el directorio de destino? (en cambio, me gustaría agregar al contenido de la carpeta de destino)

Daniel Böhmer
fuente
Sí, es molesto cuando un programa / utilidad útil no tiene esa opción "¡si tan solo pudiera ..."! En este caso "--noclobber"!
MikeW

Respuestas:

140

Use rsyncy pase -usi solo desea actualizar los archivos que son más nuevos en el directorio original, o --ignore-existingpara omitir todos los archivos que ya existen en el destino.

rsync -au /local/directory/ host:/remote/directory/
rsync -a --ignore-existing /local/directory/ host:/remote/directory/

(Tenga /en cuenta el lado de la fuente: sin que rsyncse crearía /remote/directory/directory).

Gilles
fuente
@Anthon No entiendo tu comentario y no veo una respuesta o comentario de Chandra. --ignore-existingagrega sin reemplazar, ¿qué pérdida de datos ves?
Gilles
Lo siento, solo miré su primer ejemplo que es donde puede tener pérdida de datos (y en mi humilde opinión no es lo que solicitó el OP), si incluye --no ignorar la pérdida de datos existente no debería suceder.
Anthon
Esto no ayuda si el sistema remoto no tiene rsyncfácilmente disponible ... (Como Win32-OpenSSH)
Gert van den Berg
@GertvandenBerg rsync es bastante fácil de instalar en Windows, no más difícil que SSH.
Gilles
@Gilles: Cierto, pero todas las opciones parecen involucrar archivos DLL de Cygwin ... (El estado actual del puerto MS de OpenSSH es tal que habilitar la compresión en scp es suficiente para romper SCP ...) (Hacer que rsync funcione sobre Win32 -OpenSSH también parece no trivial, es de esperar que mejore con el tiempo) (Solaris 10 es el otro ejemplo, donde --rsync-pathse necesita un paquete de terceros )
Gert van den Berg
82

scp sobrescribirá los archivos si tiene permisos de escritura.

En otras palabras: puede scpomitir eficazmente dichos archivos eliminando temporalmente los permisos de escritura (si es el propietario de los archivos).

Reembolsar
fuente
55
Gracias por esto. Fue exactamente el truco que estaba buscando.
sacarina
asegúrese de copiar los archivos de nuevo, agregue un * para hacerlo. Ejemploscp -r [email protected]:/location/of/files/* /local/location/
Rick
1
encontrar . -type f -exec chown root: root {} \;
ling
1
En el caso poco común de que se espera que solo se sobrescriban algunos de los archivos del directorio (si no están "protegidos") y que los permisos de los archivos no son uniformes en todos los archivos, es posible que esta solución no funcione. De lo contrario, es bastante simple y efectivo.
sancho.s
Para hacer esto en Windows, seleccione todos los archivos, haga clic derecho -> propiedades -> solo lectura
BenJammin
12

Puede copiar solo archivos nuevos por fecha. Utilizarfind

scp  `find /data/*.gz -type f -mtime +7` USER@SERVER:/backup/
Naks
fuente
¿Qué significa +7?
Francis Kim
@FrancisKim significa modificado hace 7 días. Entonces, esta consulta selecciona cualquier archivo * .gz modificado en los últimos 7 días
Vadim Eremeev
44
¿No implica +7 realmente hace más de 7 días?
Jeff H.
1
Sí, significa "hace más de 7 días". No tengo idea de quién votó por esto.
Stefan Reich
9

Si puede hacer que el contenido del archivo de destino sea de solo lectura:

find . -type f -exec chmod a-w '{}' \;

antes de ejecutar scp(se quejará y omitirá los archivos existentes).

Y cámbielos nuevamente después ( chmod +wpara obtener un valor basado en umask). Si no todos los archivos tienen permiso de escritura de acuerdo con su umask, de alguna manera tendría que almacenar los permisos para poder restaurarlos.

(La respuesta de Gilles sobrescribe los archivos existentes si localmente son más nuevos, perdí datos valiosos de esa manera. No entiendo por qué esa respuesta incorrecta y dañina tiene tantos votos positivos).

Mohad
fuente
2
No lo entiendo: ¿cómo te hizo rsync --ignore-existingperder datos?
Gilles
44
Tengo el error find: missing argument to '-exec'de utilizar este comando, y en su lugar tuvo que usar: find . -type f -exec chmod a-w {} \;. Mi Linux es malo, mmm.
wpearse
Esta es una respuesta mejor y más segura. El comando correcto para cambiar el permiso es como @wpearse mencionó:find . -type f -exec chmod a-w {} \;
Amir
6

Tenía una tarea similar, en mi caso no podía usar rsync, csynco porque mi fusible de almacenamiento sólo tiene SFTP. rsyncno se pudo cambiar la fecha y la hora del archivo, algunas otras utilidades (como csync) me mostraron otros errores: " No se puede crear el archivo temporal Se detectó una distorsión del reloj ".

Si tiene acceso al servidor de almacenamiento, simplemente instale openssh-servero inicie rsynccomo demonio aquí.

En mi caso, no pude hacer esto y la solución fue: lftp . lftpEl uso de la sincronización está a continuación:

lftp -c "open -u login,password sftp://sft.domain.tld/; \
    mirror -c --verbose=9 -e -R -L /srs/folder /rem/folder"

/src/folder- es la carpeta en mi PC, /rem/folder- es sftp://sft.domain.tld/rem/folder.

Puede encontrar páginas de manual en el enlace: http://lftp.yar.ru/lftp-man.html

negrita
fuente
6

Para copiar una gran cantidad de archivos, es más rápido manipularlos. Al usar -k también evita que tar sobrescriba los archivos al desempaquetarlos en el sistema de destino.

tar -c <source-dir> | ssh <name>@<host> 'tar -kxzf - -C <target-dir>' 
Huembi
fuente
1
Realiza una conexión remota. Primero, es la fuente, lo canaliza a la conexión ssh y lo desempaqueta en el sistema remoto.
huembi
-1

scpsobrescribe los archivos y no hay ningún interruptor que lo detenga, pero puede copiar las cosas, hacer el scp y luego copiar los archivos existentes. Ejemplos:

  1. Copie todos los archivos existentes fuera del camino

    mkdir original_files ; cp -r * original_files/
    
  2. Copie todo usando scp

    scp -r user@server:dir/* ./
    
  3. Copie los archivos originales sobre cualquier cosa que scp haya escrito sobre:

    cp -r original_files/* ./
    
A.Badger
fuente
3
Este método no ayuda cuando intentas detener archivos desde un control remoto y retomarlos donde los dejaste. Es decir, si todo el propósito es ahorrar tiempo.
Oliver Williams
-1

Otra forma de lograr esto es hacer un lsen la carpeta de destino:

En la carpeta de destino remota:

ls | awk '{print "mv " $1 " ../copied_data/"}' > mv_copied_data
scp mv_copied_data [email protected]:/path/to/source/folder

En la fuente:

cd /path/to/source/folder
chmod 777 mv_copied_data
./mv_copied_data

En destino:

scp -r [email protected]:/path/to/source/folder /path/to/destination/foldeer
Sameer Gurjar
fuente
Por favor no hagas esto. 1. No analices ls . 2. La respuesta es peligrosa si cualquier nombre de archivo contiene - >espacio de nueva línea u otros caracteres especiales. 3. Codifique un bucle for en un script de Python. Generar un programa en tiempo de ejecución es difícil y complicado (incluso cuando lo hacen programadores profesionales), por muchas razones. Generar un script de shell es aún peor: una idea horrible.
ignis