Podaj parametry scp za pomocą xargs

10

Kiedy biegnę svn st | awk '{print $2}', dostaję:

a.py
b.py
c.py

Następnie chcę scpte pliki na zdalnym serwerze. Próbowałem:

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

Ale to nie działa. Jakie jest właściwe polecenie, aby to zrobić?

Dziękuję Ci!

mitnk
źródło

Odpowiedzi:

10

Spróbuj tego. powinien działać z najnowszymi wersjami xargs.

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

alternatywnie możesz po prostu zapętlić pliki.

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

Tim Kennedy
źródło
2
Dziękuję Tim. svn st | awk '{print $2}' | xargs -J % scp % my_name@my_server:~/xargs
Często googlowałem
Twoje rozwiązanie też działa! Ale jest literówka, to -Iznie jest-iz
mitnk 18.11.11
jakiego systemu operacyjnego używasz? Używam -izna Solarisie i zawsze działa. Dzięki za wskaźnik.
Tim Kennedy,
4
POSIX xargs ma -I. Strona podręcznika AIX (6.1) mówi, że -ijest przestarzała i -Ipowinna być używana. Solaris 10 (i 9) ​​ma zarówno -ii -I.
Mat.
1
Ach, moja wiedza jest przestarzała! Używam -iod Solaris 2.5. starzenie się to smutny romans, moi przyjaciele. :)
Tim Kennedy,
4

Powodem, dla którego to nie działa, jest to, że chcesz xargsuruchomić

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

Kolejność argumentów nie odpowiada temu, co chcesz zrobić. Jednym z rozwiązań jest wymuszenie wyświetlania nazw plików przed miejscem docelowym w wierszu polecenia. Wymaga to GNU xargs (tj. Linux lub Cygwin). Chociaż jesteśmy przy tym, możemy przekazać, -d '\n'aby upewnić się, że każda nazwa pliku, która nie zawiera nowych wierszy, będzie działać (bez -dxargs spodziewa się dziwnego cytowania swoich danych wejściowych); nie jest to konieczne, jeśli pracujesz z typowymi drzewami źródłowymi oprogramowania, w których nazwy plików są zwykle bardzo oswojone.

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

Minusem tej metody jest to, że scpjest wywoływana osobno dla każdego pliku. Jeśli kopiujesz wiele małych plików, może to mieć znaczącą różnicę, ponieważ nawiązanie połączenia SSH zajmuje trochę czasu. Możesz znacznie skrócić czas na połączenie, używając połączenia głównego SSH (poza zakresem tej odpowiedzi, patrz instrukcja, a zwłaszcza opcje ControlMasteri ).ControlPath.ssh/config

Sposobem na wymuszenie argumentów we właściwym miejscu jest przejście przez powłokę pośrednią. Jest to ogólna technika zmiany kolejności argumentów podczas używania xargslub find … -exec.

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

Inną możliwością jest użycie rsynczamiast scp. Możesz przekazać rsynclistę nazw plików na standardowe wejście. Ponieważ rsyncoczekuje ona listy wzorców, a nie listy nazw plików, wymaga to, aby nazwy plików nie zawierały znaków wieloznacznych (w szczególności żadnych znaków nowej linii, żadnych znaków \[*?początkowych #lub ;).

svn st | awk '{print $2}' |
rsync -a --include-from=- --exclude='*' . my_name@my_server:~/
Gilles „SO- przestań być zły”
źródło