restic mount no funciona sin FUSE: ls y dump para sacar un fichero sin restaurar
restic mount falló con exit 1 (no existe /dev/fuse). Con restic dump se extrajo un fichero de 20 MiB en 0,80 s, idéntico al original (cmp), y la versión antigua de un fichero de texto desde el primer snapshot; también una carpeta como tar y zip. Una ruta inexistente dio exit 1.
Contenido
Este artículo no contiene enlaces de afiliado.
restic mount monta el repositorio como un directorio para que navegues por los snapshots y copies lo que necesites. Es cómodo, pero depende de FUSE. Se probó qué pasa cuando FUSE no está, y se comprobó la alternativa que no lo necesita: restic ls y restic dump.
Condiciones: restic 0.16.4 en Linux arm64, dentro de un contenedor sin /dev/fuse y sin permisos de root. Repositorio local, contraseña desechable, dos snapshots de una carpeta con un fichero de 20 MiB aleatorio y dos ficheros de texto (uno de ellos editado entre los dos snapshots). No se probó restic mount funcionando, así que no se puede decir nada medido sobre --allow-other, el desmontaje (fusermount -u) ni su rendimiento. No se probó con repositorios remotos. Script completo al final.
restic mount sin FUSE
El ejecutable fusermount estaba instalado, pero el dispositivo no:
ls: cannot access '/dev/fuse': No such file or directory
fusermount: exit status 1
mount helper error: fusermount: fuse device not found, try 'modprobe fuse' first
restic mount terminó con exit 1. No se probó cómo habilitar FUSE en el contenedor. Si estás en esta situación (contenedor, servidor sin FUSE, sistema donde no puedes cargar el módulo), no hace falta montar nada.
ls: ver qué hay en un snapshot
restic ls latest lista todo el contenido del snapshot, incluidas las carpetas padre de la ruta copiada. --long añade permisos, propietario, tamaño y fecha. Si das una ruta, restringe el listado a ella:
drwxr-xr-x 10002 10002 0 2026-10-29 04:03:24 .../data/docs
-rw-r--r-- 10002 10002 18 2026-10-29 04:03:25 .../data/docs/nota.txt
-rw-r--r-- 10002 10002 9 2026-10-29 04:03:24 .../data/docs/otro.txt
La ruta que pasas debe ser la absoluta con la que se hizo la copia.
dump: sacar un fichero sin restaurar
restic dump SNAPSHOT RUTA escribe el contenido en la salida estándar, así que se redirige a un fichero o se encadena con una tubería.
| Prueba | Resultado |
|---|---|
nota.txt en el snapshot antiguo |
version 1 |
nota.txt en latest |
version 2 editada |
grande.bin (20 MiB) con > fichero |
exit 0, 0,80 s, cmp idéntico al original |
carpeta docs |
tar por defecto, con los 2 ficheros |
carpeta docs con --archive zip |
zip con los 2 ficheros |
ruta /no/existe |
Fatal: cannot dump file: path "/no" not found in snapshot, exit 1 |
ruta relativa data/docs/nota.txt |
Fatal: cannot dump file: path "/data" not found in snapshot, exit 1 |
contraseña incorrecta (ls) |
Fatal: wrong password or no key found, exit 1 |
Detalles que importan
- Para recuperar una versión anterior de un fichero basta indicar el ID del snapshot antiguo: el primero devolvió
version 1y el últimoversion 2 editada. No hay que restaurar nada a disco. - Las rutas dentro del tar y del zip no llevan la barra inicial (
tmp/s/r/data/docs/nota.txten la prueba): al extraerlas se recrea toda la ruta completa, no solodocs/. Úsalo contar -x --strip-components, que no se probó aquí. - Un fichero grande se escribe a la salida estándar: si no rediriges, lo verás volcado en la terminal. En la prueba la salida no era un terminal, y no se probó qué hace restic en ese caso.
- Los mensajes de error de ruta enseñan solo el primer componente que falta (
/no,/data), no la ruta completa. Si te sale "not found", mira primero conrestic ls. - El tiempo de 0,80 s es de un solo fichero en disco local, sin cifrado remoto; no es una cifra extrapolable a un repositorio en la nube.
Para restaurar con comprobación, mira restaurar una copia como prueba.
Script completo
#!/bin/bash
# restic mount (fails without FUSE here), then restic ls and restic dump instead of a restore. Usage: test-restic-dump-ls.sh WORKDIR
W=$1; rm -rf "$W"; mkdir -p "$W/data/docs" "$W/data/fotos" "$W/mnt" "$W/out"
export RESTIC_PASSWORD=prueba-desechable
R="$W/repo"; restic init -r "$R" >/dev/null
echo "version 1" > "$W/data/docs/nota.txt"
head -c 20M /dev/urandom > "$W/data/fotos/grande.bin"
echo "sensible" > "$W/data/docs/otro.txt"
restic backup -r "$R" "$W/data" >/dev/null 2>&1
echo "version 2 editada" > "$W/data/docs/nota.txt"
restic backup -r "$R" "$W/data" >/dev/null 2>&1
echo "== /dev/fuse"; ls -l /dev/fuse 2>&1; echo "uid=$(id -u)"
echo "== restic mount"; timeout 20 restic mount -r "$R" "$W/mnt" 2>&1 | head -5; echo "exit=${PIPESTATUS[0]}"
echo "== snapshots"; restic snapshots -r "$R" --compact 2>&1 | tail -5
echo "== ls latest"; restic ls -r "$R" latest 2>&1 | sed "s#$W#W#"
echo "== ls --long latest (un directorio)"; restic ls -r "$R" --long latest "$W/data/docs" 2>&1 | sed "s#$W#W#"
echo "== ls con subruta sin snapshots intermedios"; restic ls -r "$R" latest "$W/data/fotos" 2>&1 | sed "s#$W#W#"
ID1=$(restic snapshots -r "$R" --json | python3 -c 'import json,sys; print(json.load(sys.stdin)[0]["short_id"])')
echo "== dump de nota.txt en el snapshot antiguo ($ID1) y en latest"
restic dump -r "$R" "$ID1" "$W/data/docs/nota.txt"; echo "exit=$?"
restic dump -r "$R" latest "$W/data/docs/nota.txt"; echo "exit=$?"
echo "== dump de grande.bin a fichero con redirección, comparado con el original"
s=$EPOCHREALTIME; restic dump -r "$R" latest "$W/data/fotos/grande.bin" > "$W/out/grande.bin"; echo "exit=$? $(echo "$EPOCHREALTIME $s" | awk '{printf "%.2f s", $1-$2}')"
cmp "$W/data/fotos/grande.bin" "$W/out/grande.bin" && echo "idéntico"
echo "== dump de un directorio (tar por defecto)"
restic dump -r "$R" latest "$W/data/docs" > "$W/out/docs.tar"; echo "exit=$?"; tar tf "$W/out/docs.tar"
echo "== dump --archive zip"
restic dump -r "$R" --archive zip latest "$W/data/docs" > "$W/out/docs.zip"; echo "exit=$?"; python3 -c "import zipfile,sys; print(zipfile.ZipFile(sys.argv[1]).namelist())" "$W/out/docs.zip"
echo "== dump de un fichero de texto a una tubería"
restic dump -r "$R" latest "$W/data/docs/otro.txt" | cat
echo "== ruta que no existe"
restic dump -r "$R" latest /no/existe 2>&1; echo "exit=${PIPESTATUS[0]}"
echo "== ruta relativa en vez de absoluta"
restic dump -r "$R" latest data/docs/nota.txt 2>&1; echo "exit=${PIPESTATUS[0]}"
echo "== contraseña incorrecta"
RESTIC_PASSWORD=mala restic ls -r "$R" latest 2>&1 | tail -1; echo "exit=${PIPESTATUS[0]}"