Fornecer parâmetros para scp com xargs

8

Quando executo svn st | awk '{print $2}' , obtenho:

a.py
b.py
c.py

Então eu quero scp desses arquivos para um servidor remoto. Eu tentei:

svn st | awk '{print $2}' | xargs scp my_name@my_server:~/

Mas isso não funciona. Qual é o comando certo para fazer isso?

Obrigado!

    
por mitnk 18.11.2011 / 05:29

2 respostas

10

tente isso. deve funcionar com versões recentes do xargs.

svn st | awk '{print $2}' | xargs -iz scp z my_name@my_server:

alternadamente, você poderia apenas repetir os arquivos.

for file in $(svn st | awk '{print $2}'); do scp $file my_name@my_server: ; done

    
por 18.11.2011 / 06:55
3

A razão pela qual isso não funciona é que você está dizendo xargs para executar

scp my_name@my_server:~/ a.py b.py c.py

A ordem dos argumentos não corresponde ao que você deseja fazer. Uma solução é forçar os nomes dos arquivos a aparecerem antes do destino na linha de comando. Isso requer GNU xargs (ou seja, Linux ou Cygwin). Enquanto estamos nisso, podemos passar -d '\n' para garantir que qualquer nome de arquivo que não contenha novas linhas funcione (sem -d , xargs espera alguma citação estranha de sua entrada); isso não é necessário se você trabalha com árvores de fontes de software típicas, nas quais os nomes de arquivos tendem a ser muito mansos.

svn st | awk '{print $2}' |
xargs -d\n -I{} scp {} my_name@my_server:~/

Uma desvantagem desse método é que scp é chamado separadamente para cada arquivo. Se você estiver copiando muitos arquivos pequenos, isso pode fazer uma diferença significativa, já que a conexão SSH demora um pouco para ser estabelecida. Você pode reduzir bastante o tempo por conexão usando uma conexão mestre SSH (que supera o escopo dessa resposta, consulte o manual, especialmente as opções ControlMaster e ControlPath em .ssh/config ).

Uma maneira de forçar os argumentos a estar no lugar certo é passar por um shell intermediário. Essa é uma técnica geral para reordenar argumentos ao usar xargs ou find … -exec .

svn st | awk '{print $2}' |
xargs -d\n sh -c 'scp "$@" "$0" my_name@my_server:~/

Outra possibilidade é usar rsync em vez de scp . Você pode passar rsync uma lista de nomes de arquivos na entrada padrão. Como rsync espera uma lista de padrões e não uma lista de nomes de arquivos, isso requer que os nomes dos arquivos não contenham caracteres curinga (especificamente, sem novas linhas, sem \[*? e sem% inicial # ou ; ) .

svn st | awk '{print $2}' |
rsync -a --include-from=- --exclude='*' . my_name@my_server:~/
    
por 19.11.2011 / 01:49

Tags