Geben Sie mit xargs Parameter für scp an

10

Wenn ich renne svn st | awk '{print $2}', bekomme ich:

a.py
b.py
c.py

Dann möchte ich scpdiese Dateien auf einen Remote-Server übertragen. Ich habe versucht:

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

Aber es funktioniert nicht. Was ist der richtige Befehl, um dies zu tun?

Danke!

mitnk
quelle

Antworten:

10

Versuche dies. sollte mit neueren Versionen von xargs funktionieren.

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

Alternativ können Sie auch einfach die Dateien durchlaufen.

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

Tim Kennedy
quelle
2
Danke Tim. Ich habe viel gegoogelt und die Lösung gefunden: svn st | awk '{print $2}' | xargs -J % scp % my_name@my_server:~/Ich hätte die Manpage von lesen sollen, xargsbevor ich gefragt habe;)
Mitnk
Und Ihre Lösung funktioniert auch! Aber es gibt einen Tippfehler, es ist -Iznicht-iz
Mitnk
Welches Betriebssystem verwenden Sie? Ich benutze -izunter Solaris und es funktioniert immer. Danke für den Zeiger.
Tim Kennedy
4
POSIX xargs hat -I. Die AIX (6.1) -Manpage sagt, dass sie -iveraltet ist und -Iverwendet werden sollte. Solaris 10 (und 9) hat beide -iund -I.
Mat
1
Ah, mein Wissen ist veraltet! Ich benutze -iseit Solaris 2.5. alt zu werden ist eine traurige Angelegenheit, meine Freunde. :)
Tim Kennedy
4

Der Grund, warum dies nicht funktioniert, ist, dass Sie sagen xargs, dass Sie rennen sollen

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

Die Reihenfolge der Argumente entspricht nicht dem, was Sie tun möchten. Eine Lösung besteht darin, zu erzwingen, dass die Dateinamen in der Befehlszeile vor dem Ziel angezeigt werden. Dies erfordert GNU xargs (dh Linux oder Cygwin). Während wir gerade dabei sind, können wir -d '\n'sicherstellen, dass jeder Dateiname, der keine Zeilenumbrüche enthält, funktioniert (ohne dass -dxargs ein seltsames Zitat seiner Eingabe erwartet). Dies ist nicht erforderlich, wenn Sie mit typischen Software-Quellbäumen arbeiten, in denen Dateinamen in der Regel sehr zahm sind.

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

Ein Nachteil dieser Methode ist, dass scpsie für jede Datei separat aufgerufen wird. Wenn Sie viele kleine Dateien kopieren, kann dies einen erheblichen Unterschied bewirken, da der Aufbau einer SSH-Verbindung einige Zeit in Anspruch nimmt. Sie können die Zeit pro Verbindung erheblich verkürzen, indem Sie eine SSH-Master-Verbindung verwenden (dies liegt außerhalb des Bereichs dieser Antwort, siehe Handbuch, insbesondere ControlMasterund ControlPathOptionen in .ssh/config).

Eine Möglichkeit, die Argumente an die richtige Stelle zu bringen, besteht darin, eine Zwischenschale zu durchlaufen. Dies ist eine allgemeine Technik zum Neuordnen von Argumenten bei Verwendung von xargsoder find … -exec.

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

Eine andere Möglichkeit ist, rsyncanstelle von zu verwenden scp. Sie können rsynceine Liste von Dateinamen bei der Standardeingabe übergeben. Da rsynceine Liste von Mustern und keine Liste von Dateinamen erwartet wird, müssen Ihre Dateinamen keine Platzhalterzeichen enthalten (insbesondere keine Zeilenumbrüche, keine \[*?und keine Initialen #oder ;).

svn st | awk '{print $2}' |
rsync -a --include-from=- --exclude='*' . my_name@my_server:~/
Gilles 'SO - hör auf böse zu sein'
quelle