Como copiar arquivos usando scp do host remoto quando o arquivo tiver espaços

2

Eu preciso copiar um arquivo do host remoto para o meu diretório local usando scm onde um arquivo tem espaços, pois não corrigi o problema por ssh para esse host e scp o arquivo de volta. Mas eu 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 isto:

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

mas tem 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.txt e file%20that%20have%20spaces.txt

    
por jcubic 08.04.2017 / 22:59

2 respostas

3

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

Isto tem vantagens, em particular, permite que você especifique curingas. É também o que permite usar ~ para o diretório inicial remoto (mas os nomes de arquivos são relativos ao diretório inicial remoto, portanto, 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 contiverem caracteres especiais. Você também precisa tomar cuidado se quiser filtrar os nomes de arquivos permitidos no servidor (especialmente para uma conta restrita que não tenha privilégios de comando de shell).

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

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

Sua tentativa com duas barras invertidas não funcionou porque \ é analisado pelo shell local como barra invertida seguida por um espaço que separa os argumentos; você precisa enviar backslash-space para o host remoto, e tanto a barra invertida quanto o espaço precisam ser protegidos da análise pelo shell local, então 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 um shell, portanto, é uma maneira de evitar problemas com caracteres especiais. O SSHFS baseia-se no SFTP e fornece acesso direto a arquivos remotos, 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
    
por 09.04.2017 / 02:44
2

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

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

Tags