Fournir des paramètres à scp avec xargs

10

Quand je cours svn st | awk '{print $2}', je reçois:

a.py
b.py
c.py

Ensuite, je veux scpces fichiers sur un serveur distant. J'ai essayé:

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

Mais ça ne marche pas. Quelle est la bonne commande pour ce faire?

Je vous remercie!

mitnk
la source

Réponses:

10

essaye ça. devrait fonctionner avec les versions récentes de xargs.

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

alternativement, vous pouvez simplement parcourir les fichiers en boucle.

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

Tim Kennedy
la source
2
Merci Tim. J'ai beaucoup recherché sur svn st | awk '{print $2}' | xargs -J % scp % my_name@my_server:~/xargs
Google
Et votre solution fonctionne aussi! Mais il y a une faute de frappe, ce n'est -Izpas le cas-iz
mitnk
quel système d'exploitation utilisez-vous? J'utilise -izsur Solaris, et cela fonctionne toujours. Merci pour le pointeur.
Tim Kennedy
4
POSIX xargs a -I. La page de manuel AIX (6.1) indique qu'elle -iest obsolète et -Idoit être utilisée. Solaris 10 (et 9) possède les deux -iet -I.
Mat
1
Ah, mes connaissances sont obsolètes! J'utilise -idepuis Solaris 2.5. vieillir est une triste affaire, mes amis. :)
Tim Kennedy
4

La raison pour laquelle cela ne fonctionne pas est que vous dites xargsde courir

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

L'ordre des arguments ne correspond pas à ce que vous voulez faire. Une solution consiste à forcer les noms de fichiers à apparaître avant la destination sur la ligne de commande. Cela nécessite des xargs GNU (c'est-à-dire Linux ou Cygwin). Pendant que nous y sommes, nous pouvons passer -d '\n'pour nous assurer que tout nom de fichier qui ne contient pas de sauts de ligne fonctionnera (sans -d, xargs attend une citation étrange de son entrée); cela n'est pas nécessaire si vous travaillez avec des arborescences de sources logicielles typiques, dans lesquelles les noms de fichiers ont tendance à être très apprivoisés.

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

Un inconvénient de cette méthode est qu'elle scpest appelée séparément pour chaque fichier. Si vous copiez beaucoup de petits fichiers, cela peut faire une différence significative, car une connexion SSH prend un peu de temps à établir. Vous pouvez considérablement raccourcir le temps par connexion en utilisant une connexion maître SSH (cela dépasse la portée de cette réponse, voir le manuel, en particulier les options ControlMasteret ).ControlPath.ssh/config

Un moyen de forcer les arguments à être au bon endroit est de passer par un shell intermédiaire. Il s'agit d'une technique générale pour réorganiser les arguments lors de l'utilisation de xargsou find … -exec.

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

Une autre possibilité consiste à utiliser à la rsyncplace de scp. Vous pouvez transmettre rsyncune liste de noms de fichiers sur une entrée standard. Étant donné qu'il rsyncattend une liste de modèles et non une liste de noms de fichiers, cela nécessite que vos noms de fichiers ne contiennent aucun caractère générique (en particulier, pas de retour à la ligne, pas \[*?et pas d'initiale #ou ;).

svn st | awk '{print $2}' |
rsync -a --include-from=- --exclude='*' . my_name@my_server:~/
Gilles 'SO- arrête d'être méchant'
la source