SCP sobrescreve arquivos com cifrões

3

Eu tenho este arquivos:

A.class
A$1.class
A$2.class

E um script bash com algo como:

for i in *; do
    scp "${i}" foo@bar:/tmp/;
done

Isso funciona bem. Todos os três arquivos são copiados. O problema é com o seguinte:

for i in *; do
    scp "${i}" foo@bar:/tmp/"${i}";
    scp "${i}" foo@bar:"/tmp/${i}";
    scp "${i}" "foo@bar:/tmp/${i}";
done

Em qualquer um desses casos, o SCP copia todos os arquivos, mas para o mesmo arquivo A.class .

Alguma ideia? Obrigado!

    
por Eldelshell 11.04.2012 / 16:21

3 respostas

3

Usar scp -v mostra alguns detalhes sobre como o scp funciona:

debug1: Sending command: scp -v -t /tmp/A$2.class
Sending file modes: C0644 0 A$2.class
Sink: C0644 0 A$2.class
A$2.class                                     100%    0     0.0KB/s   00:00    

Essencialmente, como o scp é executado sobre o ssh, ele precisa de um shell para executar seu comando e, como o $ não é ignorado, o shell remoto interpreta $2 como uma string vazia, o que torna o nome de destino A.class .

Existem duas maneiras de resolver isso. Primeiro, você poderia simplesmente usar o * glob no seu comando scp diretamente:

scp * foo@bar:/tmp/

Mas eu tenho certeza que você tem alguma outra necessidade de usar um loop, então aqui está como corrigi-lo no loop:

for i in *; do
    scp "${i}" "foo@bar:'/tmp/${i}'"
done

Verificando a saída de scp -v agora mostra:

debug1: Sending command: scp -v -t '/tmp/A$2.class'

Sucesso! As aspas simples impedirão que o shell remoto execute a expansão de variáveis.

ATUALIZAÇÃO: Como o argumento é interpretado pelo shell como um argumento, você pode fazer coisas assim:

scp foo@bar:'$(which ssh)' .

Ou pipelines de shell ainda mais complicados que resultam em um nome de arquivo. Isso não é um problema de segurança, pois se você pode se conectar com o scp, você pode se conectar com o ssh. Mas isso pode tornar as coisas mais convenientes para alguém.

    
por 11.04.2012 / 16:37
1

Uma solução seria usar o find para isso:

find . -name A\*.class -print0|xargs -0 -i _PLACEHOLDER_ scp _PLACEHOLDER_ foo@bar:/tmp/_PLACEHOLDER_

A ideia é evitar a expansão do shell.

    
por 11.04.2012 / 16:31
1

Acho que isso é causado pelo "${i}" sendo expandido localmente para A$1.class e, em seguida, enviado para o controle remoto, que o expande para A.class , pois o $1 é "" . Você pode contornar isso com

scp "${i}" foo@bar:/tmp/'${i}';
    
por 11.04.2012 / 16:31

Tags