Proporcione parámetros para scp con xargs

10

Cuando corro svn st | awk '{print $2}', obtengo:

a.py
b.py
c.py

Entonces quiero scpestos archivos a un servidor remoto. Yo he tratado:

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

Pero no funciona. ¿Cuál es el comando correcto para hacer esto?

¡Gracias!

mitnk
fuente

Respuestas:

10

prueba esto. debería funcionar con versiones recientes de xargs.

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

alternativamente, puede simplemente recorrer los archivos.

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

Tim Kennedy
fuente
2
Gracias Tim Busqué en Google mucho y encontré la solución: svn st | awk '{print $2}' | xargs -J % scp % my_name@my_server:~/que debería haber leído la página del manual de xargsantes de pedir;)
mitnk
¡Y tu solución también funciona! Pero hay un error tipográfico, es -Izno-iz
mitnk
¿Qué sistema operativo estás usando? Yo uso -izen Solaris, y siempre funciona. Gracias por la anotación.
Tim Kennedy el
44
POSIX tiene xargs-I . La página de manual de AIX (6.1) dice que -iestá obsoleta y que -Idebe usarse. Solaris 10 (y 9) tiene ambos -iy -I.
Mat
1
¡Ah, mi conocimiento es obsoleto! He estado usando -idesde Solaris 2.5. envejecer es un asunto triste, mis amigos. :)
Tim Kennedy
4

La razón por la que esto no funciona es porque le estás diciendo xargsque corras

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

El orden de los argumentos no corresponde a lo que quieres hacer. Una solución es forzar que los nombres de los archivos aparezcan antes del destino en la línea de comando. Esto requiere GNU xargs (es decir, Linux o Cygwin). Mientras estamos en eso, podemos pasar -d '\n'para asegurarnos de que cualquier nombre de archivo que no contenga nuevas líneas funcionará (sin -d, xargs espera alguna cita extraña de su entrada); esto no es necesario si trabaja con árboles de fuentes de software típicos, en los que los nombres de los archivos tienden a ser muy mansos.

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

Una desventaja de este método es que scpse llama por separado para cada archivo. Si está copiando muchos archivos pequeños, eso puede marcar una diferencia significativa, ya que una conexión SSH tarda un poco en establecerse. Puede acortar en gran medida el tiempo por conexión mediante el uso de una conexión maestra SSH (que está fuera del alcance de esta respuesta, consulte el manual, especialmente las opciones ControlMastery ).ControlPath.ssh/config

Una forma de forzar a los argumentos a estar en el lugar correcto es pasar por un caparazón intermedio. Esta es una técnica general para reordenar argumentos cuando se usa xargso find … -exec.

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

Otra posibilidad es usar en rsynclugar de scp. Puede pasar rsyncuna lista de nombres de archivo en la entrada estándar. Dado que rsyncespera una lista de patrones y no una lista de nombres de archivos, esto requiere que los nombres de sus archivos no contengan caracteres comodín (específicamente, no hay líneas nuevas, no \[*?y no iniciales #o ;).

svn st | awk '{print $2}' |
rsync -a --include-from=- --exclude='*' . my_name@my_server:~/
Gilles 'SO- deja de ser malvado'
fuente