.png)
Veo muchas preguntas relacionadas con esto, pero no todas mis restricciones, así que comenzaré con mis restricciones.
Restricciones:
- Quiero copiar recursivamente un directorio remoto.
- No puedo controlar la configuración del servidor remoto en absoluto.
- No tengo permisos de escritura en ese directorio en la máquina remota.
- Cuando lo intento
get -r
, copia el directorio.sin localpermisos de escritura tampoco. - Luego, cuando intenta copiar recursivamente archivos y carpetas anidados en el directorio remoto, aparece un error en ellocaldirectorio donde no me dio permisos de escritura.
- No puedo instalar nuevo software en mi máquina. (necesita una
sftp
solución pura con "OpenSSH_7.9p1, LibreSSL 2.7.3")
Pregunta:
¿Puedo copiar recursivamente los directorios remotos con puro
sftp
y sinlocalerror de permisos?
Respuesta1
ACTUALIZAR: OpenSSH 8.5 lanzado 2021-03 soluciona este problema; verhttp://www.openssh.com/txt/release-8.5en Corrige errores el elemento para bz#3222.
Aparte: OpenSSH 7.9 se lanzó en 2018-10; no puede tener "[viene] en [una] Mac hace ~5 años". Te has actualizado de alguna manera.
Tienes razón; download_dir_internal
in sftp-client.c
crea un nuevo directorio local con los mismos permisos que el remoto, si está disponible, excepto enmascarado por 01777, es decir, excluyendo suid y sgid, que son bastante raros y muy probablemente no ocurren en su caso. La bandera -p
(o -P
) es necesaria para establecer permisos paraarchivospero se ignora para los directorios.
Sin embargo, si el directorio ya existe, sftp ignora el error EEXIST. Entonces, si primero crea todos los directorios (vacíos)conescribir permisos y luego hacerlo get -r
debería funcionar. No veo ninguna manera en sftp delistarecursivamente, así que a menos que ya conozcas la estructura del directorio o tengas una forma de ejecutar algo como find /mydir -type d
en el control remoto, esto se pone un poco feo:
#!/bin/bash # or other location as necessary
REMOTE=(user@host) # array so can add _separated_ options like -i idfile -P port if needed
IFS=$'\n'
all=( )
new=( $( echo ls -n | sftp ${REMOTE[@]} | awk '/^d/{print substr($0,57)}' ) )
while [[ ${#new[@]} -gt 0 ]]; do
all+=( "${new[@]}" )
new=( $( printf "ls -n %s\n" "${new[@]}" \
| sftp ${REMOTE[@]} | awk '/^d/{print substr($0,57)}' ) )
done
mkdir "${all[@]}" # with umask NOT including 200!
# or if (maybe) large enough to hit ARG_MAX
printf '%s\n' "${all[@]}" | xargs mkdir
# if dirnames (can) contain any SP TAB " ' \
# use -d'\n' on GNU but you're on your own otherwise
# (and Macs mostly don't have GNU)
(No probado en Mac porque no tengo uno, pero creo que todo aquí es portátil excepto lo que se indica).