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:~/