<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Rsync on inetshell</title><link>https://inet.sh/es/tags/rsync/</link><description>Recent content in Rsync on inetshell</description><generator>Hugo</generator><language>es</language><lastBuildDate>Sat, 26 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://inet.sh/es/tags/rsync/index.xml" rel="self" type="application/rss+xml"/><item><title>rsync: reanudar copias gigantes, copiar solo la estructura y decidir qué cuenta como 'cambiado'</title><link>https://inet.sh/es/posts/linux/rsync-reanudar-copias-grandes/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/es/posts/linux/rsync-reanudar-copias-grandes/</guid><description>Tres cosas de rsync que no vienen en el tutorial típico: cómo reanudar la copia de un archivo de cientos de GB sin volver a empezar (--partial --append-verify --inplace), cómo replicar solo el árbol de directorios sin archivos (filtros + */ y - *), y qué hacen de verdad --size-only, --ignore-times y --checksum. Con el cipher de SSH que más rinde y cómo verificar la copia al final.</description><content:encoded><![CDATA[<h2 id="en-corto">En corto</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># Reanudar un archivo enorme (imagen de VM, dump) sin empezar de cero</span>
</span></span><span class="line"><span class="cl">rsync -av --partial --append-verify --inplace --progress origen/ host:/destino/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Solo el árbol de directorios, sin archivos</span>
</span></span><span class="line"><span class="cl">rsync -a -f<span class="s1">&#39;+ */&#39;</span> -f<span class="s1">&#39;- *&#39;</span> origen/ destino/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Verificar una copia terminada sin copiar nada</span>
</span></span><span class="line"><span class="cl">rsync -avn --checksum --itemize-changes origen/ host:/destino/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Otro puerto SSH</span>
</span></span><span class="line"><span class="cl">rsync -av -e <span class="s1">&#39;ssh -p 2222&#39;</span> origen/ host:/destino/
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="cómo-decide-rsync-qué-copiar">Cómo decide rsync qué copiar</h2>
<p>Antes de mover un byte, rsync compara cada archivo con su copia en destino usando hasta tres cosas: <strong>tamaño</strong>, <strong>fecha de modificación</strong> y <strong>checksum del contenido</strong>. Por defecto usa las dos primeras (un <code>stat</code>, gratis); la tercera obliga a leer el archivo entero en los dos lados.</p>
<table>
  <thead>
      <tr>
          <th>Opción</th>
          <th>Compara</th>
          <th>Copia el archivo si…</th>
          <th>Cuándo</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>(por defecto)</td>
          <td>tamaño + mtime</td>
          <td>difiere cualquiera de los dos</td>
          <td>Casi siempre</td>
      </tr>
      <tr>
          <td><code>--size-only</code></td>
          <td>tamaño</td>
          <td>el tamaño difiere</td>
          <td>Las fechas no son de fiar (restauraciones, FAT, <code>touch</code> masivos) y aceptas perder cambios que no cambian el tamaño</td>
      </tr>
      <tr>
          <td><code>--checksum</code> / <code>-c</code></td>
          <td>tamaño + checksum</td>
          <td>el tamaño o el contenido difieren; ignora la fecha</td>
          <td>Verificar integridad; builds que reinician fechas a 1970</td>
      </tr>
      <tr>
          <td><code>--ignore-times</code> / <code>-I</code></td>
          <td>nada</td>
          <td>siempre</td>
          <td>Forzar la recopia de todo</td>
      </tr>
  </tbody>
</table>
<p><code>--checksum</code> solo calcula el hash cuando el tamaño coincide, pero aun así lee cada archivo completo: sobre terabytes es lento, no es &ldquo;más seguro por defecto&rdquo;.</p>
<h2 id="reanudar-transferencias-grandes">Reanudar transferencias grandes</h2>
<p>Sin opciones, si la conexión se corta a mitad de un archivo de 200 GB, rsync <strong>borra el trozo</strong> y la siguiente pasada empieza de cero. Tres opciones cambian eso:</p>
<ul>
<li><code>--partial</code> conserva el archivo a medias. Mejor <code>--partial-dir=.rsync-partial</code>: lo guarda en un subdirectorio y el destino nunca expone un archivo truncado.</li>
<li><code>--append-verify</code> retoma a partir del tamaño que ya tiene el destino, dando por bueno lo que hay, y al terminar verifica el checksum del archivo completo; si no cuadra, lo reenvía entero. Sirve para archivos que se escriben de forma secuencial (una imagen que se está copiando, un dump, un vídeo). <code>--append</code> a secas, sin verificación, no lo uses.</li>
<li><code>--inplace</code> escribe directamente sobre el archivo destino en vez de un temporal más <code>rename</code>. Lo necesita <code>--append-verify</code>, ahorra el doble de espacio con archivos enormes, y en destinos con snapshots (ZFS, btrfs) solo reescribe los bloques que cambiaron, así que el snapshot siguiente es pequeño. A cambio, mientras dura la copia el archivo destino es inconsistente: no lo uses sobre algo que se esté sirviendo.</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">rsync -av --partial-dir<span class="o">=</span>.rsync-partial --append-verify --inplace --progress <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  -e <span class="s1">&#39;ssh -o Compression=no -c aes128-gcm@openssh.com&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  /var/lib/vz/dump/ backup-host:/backups/vz/
</span></span></code></pre></td></tr></table>
</div>
</div><p>Sobre SSH, el cifrado es el cuello de botella en LAN: <code>aes128-gcm@openssh.com</code> con AES-NI, o <code>chacha20-poly1305@openssh.com</code> en CPUs sin AES-NI, y <code>Compression=no</code> (comprimir datos ya comprimidos solo quema CPU). <code>--bwlimit=50m</code> si compartes el enlace.</p>
<h2 id="solo-la-estructura-de-directorios">Solo la estructura de directorios</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">rsync -a -f<span class="s1">&#39;+ */&#39;</span> -f<span class="s1">&#39;- *&#39;</span> origen/ destino/
</span></span></code></pre></td></tr></table>
</div>
</div><p>Los filtros se evalúan en orden: <code>+ */</code> incluye todo lo que sea directorio; <code>- *</code> excluye el resto. Con <code>-a</code> conserva permisos y dueños. Útil para preparar un destino, para replicar un esqueleto en otro storage o para ver la forma de un dataset sin arrastrar los datos.</p>
<h2 id="verificar-al-terminar">Verificar al terminar</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">rsync -avn --checksum --itemize-changes origen/ host:/destino/
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>-n</code> no copia; <code>--itemize-changes</code> imprime una línea por diferencia. Salida vacía es copia idéntica. Sustituye a recorrer los dos lados con <code>md5sum</code> a mano y se encarga de la comparación por ti.</p>
<h2 id="trampas">Trampas</h2>
<ul>
<li><strong>La barra final cambia el resultado</strong>: <code>origen/</code> copia el contenido; <code>origen</code> crea <code>destino/origen/</code>.</li>
<li><strong><code>--delete</code> con la ruta equivocada vacía el destino.</strong> Siempre <code>-n</code> primero.</li>
<li><strong><code>--append-verify</code> sobre archivos que cambian por el medio</strong> (bases de datos, discos de VM en uso) verifica, falla y reenvía entero cada vez; ahí <code>--partial --inplace</code> sin append.</li>
<li><strong><code>-z</code></strong> comprime en vuelo: bien para texto, inútil para vídeos, ISOs, dumps <code>.gz</code> o imágenes de VM ya comprimidas.</li>
<li><strong>macOS como origen</strong>: <code>--iconv=utf-8-mac,utf-8</code> convierte los nombres de NFD a NFC en vuelo; sin eso, las tildes llegan &ldquo;raras&rdquo; a Linux (<a href="/es/posts/nextcloud/incompatible-encoding-nfc-convmv/">caso Nextcloud</a>).</li>
<li><strong>Hard links</strong> se pierden con <code>--inplace</code> si el archivo se reescribe; usa <code>-H</code> sin <code>--inplace</code> cuando importen.</li>
</ul>
]]></content:encoded></item></channel></rss>