Como copiar arquivos usando scp do host remoto quando o arquivo contém espaços

Como copiar arquivos usando scp do host remoto quando o arquivo contém espaços

Preciso copiar um arquivo do host remoto para meu diretório local usando scm onde um arquivo tem espaços, pois não resolvi o problema por ssh para aquele host e scp o arquivo de volta. Mas quero saber como copiar esse arquivo, por exemplo, pode haver um caso em que o host local não tenha o sshd instalado.

Eu tentei isso:

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

mas ocorreu um erro:

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

Eu também tentei file\\ that\\ have\\ spaces.txtefile%20that%20have%20spaces.txt

Responder1

O SSH invoca um shell no servidor (não há como contornar isso). Scp chama esse shell e informa os nomes dos arquivos que precisam ser gravados. A forma como o scp foi projetado é interpolar tudo o que você passa como nome de arquivo diretamente no comando shell remoto. Isso significa que se você tiver caracteres especiais de shell em nomes de arquivos, o que para shells Unix típicos significa espaço em branco e !"#$&'()*-;<=>?@[\]^`{|}~(alguns deles dependem do shell e da posição no nome), você precisará citá-los duas vezes: uma vez para o shell local e uma vez para o shell remoto.

Isto tem vantagens, em particular permite especificar curingas. É também o que permite usar ~o diretório inicial remoto (mas os nomes dos arquivos são relativos ao diretório inicial remoto, então você pode usar apenas [email protected]:download/…em vez de [email protected]:~/download/…). Mas a desvantagem é que você precisa tomar cuidado quando os nomes dos arquivos contêm caracteres especiais. Você também precisa tomar cuidado se quiser filtrar nomes de arquivos permitidos no servidor (especialmente para uma conta restrita que não possui privilégios de comando shell).

A maneira fácil de citar duas vezes é usar aspas simples em todo o nome e uma barra invertida antes de cada caractere especial que precisa ser protegido no lado remoto. Isso não funciona com aspas simples no nome do arquivo; escape daqueles como os quatro personagens '\''. No seu exemplo:

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

Sua tentativa com duas barras invertidas não funcionou porque \\é analisada pelo shell local como uma barra invertida seguida por um espaço que separa os argumentos; você precisa enviar barra invertida para o host remoto, e tanto a barra invertida quanto o espaço precisam ser protegidos contra análise pelo shell local, portanto, ambos precisam de uma barra invertida antes deles, ou seja, você precisa de 3 barras invertidas e um espaço.

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

O SFTP não passa por shell, então é uma forma de evitar problemas com caracteres especiais.SSHFSbaseia-se em SFTP e fornece acesso remoto direto a arquivos, para que você possa fazer

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

Responder2

A solução é usar aspas e espaço de escape:

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

informação relacionada