Cómo copiar archivos usando scp desde un host remoto cuando el archivo tiene espacios

Cómo copiar archivos usando scp desde un host remoto cuando el archivo tiene espacios

Necesito copiar un archivo desde el host remoto a mi directorio local usando scm donde un archivo tiene espacios, porque no solucioné el problema mediante ssh a ese host y devolví el archivo a scp. Pero quiero saber cómo copiar ese archivo; por ejemplo, puede haber un caso en el que el host local no tenga sshd instalado.

He probado esto:

scp [email protected]:~/download/file\ that\ have\ spaces.txt ~/download/

pero obtuve un error:

scp: /home/kuba/Pobrane/file: No such file or directory
scp: that: No such file or directory
scp: have: No such file or directory
scp: spaces.txt: No such file or directory

También lo intenté file\\ that\\ have\\ spaces.txtyfile%20that%20have%20spaces.txt

Respuesta1

SSH invoca un shell en el servidor (no hay forma de evitarlo). Scp llama a este shell y le dice los nombres de los archivos que deben escribirse. La forma en que está diseñado scp es interpolar todo lo que pase como nombre de archivo directamente en el comando de shell remoto. Esto significa que si tiene caracteres especiales de shell en los nombres de archivos, lo que para los shells típicos de Unix significa espacios en blanco y !"#$&'()*-;<=>?@[\]^`{|}~(algunos de estos dependen del shell y la posición en el nombre), deberá citarlos dos veces: una para el shell local y otra para el shell local. una vez para el shell remoto.

Esto tiene ventajas, en particular le permite especificar comodines. También es lo que le permite usar ~el directorio de inicio remoto (pero los nombres de archivos son relativos al directorio de inicio remoto, por lo que puede usarlos [email protected]:download/…en lugar de [email protected]:~/download/…). Pero la desventaja es que debes tener cuidado cuando los nombres de los archivos contengan caracteres especiales. También debe tener cuidado si desea filtrar los nombres de archivos permitidos en el servidor (especialmente para una cuenta restringida que no tiene privilegios de comando de shell).

La forma más sencilla de citar dos veces es utilizar comillas simples alrededor del nombre completo y una barra invertida antes de cada carácter especial que deba protegerse en el lado remoto. Eso no funciona con comillas simples en el nombre del archivo; escapar de ellos como los cuatro personajes '\''. En tu ejemplo:

scp '[email protected]:download/file\ that\ have\ spaces.txt' ~/download/

Su intento con dos barras invertidas no funcionó porque \\el shell local lo analiza como una barra invertida seguida de un espacio que separa los argumentos; necesita enviar barra invertida-espacio al host remoto, y tanto la barra invertida como el espacio deben estar protegidos del análisis por parte del shell local, por lo que ambos necesitan una barra invertida antes de ellos, es decir, necesita 3 barras invertidas y un espacio.

scp [email protected]:download/file\\\ that\\\ have\\\ spaces.txt ~/download/

SFTP no pasa por un shell, por lo que es una forma de evitar problemas con los caracteres especiales.SSHFSse basa en SFTP y proporciona acceso remoto directo a archivos, para que pueda hacer

mkdir remote
sshfs [email protected]: remote
cp remote/download/file\ that\ have\ spaces.txt ~/download/
fusermount -u remote
rmdir remote

Respuesta2

La solución es utilizar comillas y espacios de escape:

scp "[email protected]:~/download/file\ that\ have\ spaces.txt" ~/download/

información relacionada