Berikan parameter untuk scp dengan xargs

10

Ketika saya berlari svn st | awk '{print $2}', saya mendapatkan:

a.py
b.py
c.py

Lalu saya ingin scpfile-file ini ke server jauh. Saya telah mencoba:

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

Tapi itu tidak berhasil. Apa perintah yang tepat untuk melakukan ini?

Terima kasih!

mitnk
sumber

Jawaban:

10

coba ini. harus bekerja dengan versi terbaru xargs.

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

secara bergantian, Anda hanya bisa mengulang file.

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

Tim Kennedy
sumber
2
Terima kasih, Tim. Saya sering mencari di Google dan menemukan solusinya: svn st | awk '{print $2}' | xargs -J % scp % my_name@my_server:~/Seharusnya saya membaca halaman manual xargssebelum bertanya;)
mitnk
Dan solusi Anda juga berfungsi! Tapi ada kesalahan ketik, -Izbukan-iz
mitnk
OS apa yang kamu gunakan? Saya gunakan -izpada Solaris, dan selalu berhasil. Terima kasih untuk penunjuknya.
Tim Kennedy
4
POSIX xargs miliki -I. Halaman manual AIX (6.1) mengatakan -isudah usang dan -Iharus digunakan. Solaris 10 (dan 9) memiliki keduanya -idan -I.
Mat
1
Ah, pengetahuan saya sudah usang! Saya telah menggunakan -isejak Solaris 2.5. menjadi tua adalah urusan yang menyedihkan, teman-teman saya. :)
Tim Kennedy
4

Alasan mengapa ini tidak berhasil adalah karena Anda disuruh xargslari

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

Urutan argumen tidak sesuai dengan apa yang ingin Anda lakukan. Salah satu solusinya adalah memaksa nama file muncul sebelum tujuan pada baris perintah. Ini membutuhkan GNU xargs (yaitu Linux atau Cygwin). Sementara kita melakukannya, kita dapat -d '\n'memastikan bahwa setiap nama file yang tidak mengandung baris baru akan berfungsi (tanpa -d, xargs mengharapkan beberapa kutipan aneh dari inputnya); ini tidak perlu jika Anda bekerja dengan pohon sumber perangkat lunak khas, di mana nama file cenderung sangat jinak.

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

Kelemahan dari metode ini adalah yang scpdipanggil secara terpisah untuk setiap file. Jika Anda menyalin banyak file kecil, itu bisa membuat perbedaan yang signifikan, karena koneksi SSH membutuhkan waktu agak lama untuk dibuat. Anda dapat mempersingkat waktu per-koneksi dengan menggunakan koneksi master SSH (yang melampaui cakupan jawaban ini, lihat manual, terutama opsi ControlMasterdan ControlPathdi dalamnya .ssh/config).

Cara untuk memaksa argumen berada di tempat yang tepat adalah melalui shell perantara. Ini adalah teknik umum untuk menyusun ulang argumen saat menggunakan xargsatau find … -exec.

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

Kemungkinan lain adalah menggunakan rsyncbukan scp. Anda dapat melewati rsyncdaftar nama file pada input standar. Karena rsyncmengharapkan daftar pola dan bukan daftar nama file, ini mensyaratkan bahwa nama file Anda tidak mengandung karakter wildcard (khusus, tidak ada baris baru, tidak ada \[*?dan tidak ada inisial #atau ;).

svn st | awk '{print $2}' |
rsync -a --include-from=- --exclude='*' . my_name@my_server:~/
Gilles 'SANGAT berhenti menjadi jahat'
sumber