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