ระบุพารามิเตอร์สำหรับ scp ด้วย xargs


10

เมื่อฉันวิ่งsvn st | awk '{print $2}'ฉันจะได้รับ:

a.py
b.py
c.py

จากนั้นฉันต้องการscpไฟล์เหล่านี้ไปยังเซิร์ฟเวอร์ระยะไกล ฉันเหนื่อย:

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

แต่มันไม่ทำงาน คำสั่งที่เหมาะสมในการทำเช่นนี้คืออะไร?

ขอบคุณ!

คำตอบ:


10

ลองนี้ ควรทำงานกับ xargs รุ่นล่าสุด

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

คุณสามารถวนซ้ำได้ทั้งไฟล์

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


2
ขอบคุณทิม ฉัน googled มากและพบว่าการแก้ปัญหา: svn st | awk '{print $2}' | xargs -J % scp % my_name@my_server:~/ฉันควรจะได้อ่านหน้าคนของxargsก่อนที่จะถาม;)
mitnk

และโซลูชันของคุณก็ใช้ได้เช่นกัน! แต่มีการพิมพ์ผิดมัน-Izไม่ใช่-iz
mitnk

คุณใช้ระบบปฏิบัติการอะไร? ฉันใช้-izกับ Solaris และใช้งานได้เสมอ ขอบคุณสำหรับตัวชี้
ทิมเคนเนดี้

4
xargs POSIX-Iมี หน้า man ของ AIX (6.1) บอกว่า-iล้าสมัยและ-Iควรใช้ Solaris 10 (9) มีทั้งและ-i -I
Mat

1
อาความรู้ของฉันล้าสมัย! ฉันใช้-iมาตั้งแต่ Solaris 2.5 การแก่ขึ้นเป็นเรื่องเศร้าเพื่อนของฉัน :)
Tim Kennedy

4

สาเหตุที่ใช้ไม่ได้คือคุณกำลังบอกxargsให้เรียกใช้

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

ลำดับของอาร์กิวเมนต์ไม่ตรงกับสิ่งที่คุณต้องการทำ ทางออกหนึ่งคือบังคับให้ชื่อไฟล์ปรากฏต่อหน้าปลายทางในบรรทัดคำสั่ง สิ่งนี้ต้องใช้ GNU xargs (เช่น Linux หรือ Cygwin) ในขณะที่เรากำลังที่จะให้เราสามารถส่งผ่าน-d '\n'เพื่อให้แน่ใจว่าชื่อไฟล์ใด ๆ ที่ไม่ได้มีการขึ้นบรรทัดใหม่จะทำงาน (โดยไม่-d, xargs คาดว่าบางแปลก quoting ของปัจจัยการผลิต); นี่ไม่จำเป็นถ้าคุณทำงานกับซอร์สซอฟต์แวร์ทั่วไปซึ่งชื่อไฟล์มักจะเชื่องมาก

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

ข้อเสียของวิธีนี้scpคือเรียกว่าแยกต่างหากสำหรับทุกไฟล์ หากคุณกำลังคัดลอกไฟล์ขนาดเล็กจำนวนมากนั่นอาจสร้างความแตกต่างอย่างมีนัยสำคัญเนื่องจากการเชื่อมต่อ SSH ใช้เวลาสร้างเล็กน้อย คุณสามารถลดเวลาในการเชื่อมต่อได้อย่างมากโดยใช้การเชื่อมต่อหลัก SSH (ที่อยู่นอกขอบเขตของคำตอบนี้ดูคู่มือโดยเฉพาะอย่างยิ่งในตัวเลือกControlMasterและControlPathตัวเลือก.ssh/config)

วิธีที่จะบังคับให้ข้อโต้แย้งอยู่ในตำแหน่งที่ถูกต้องคือการผ่านเชลล์ระดับกลาง นี้เป็นเทคนิคทั่วไปที่จะมีปากเสียงสั่งซื้อใหม่เมื่อใช้หรือxargsfind … -exec

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

เป็นไปได้ก็คือการใช้แทนrsync scpคุณสามารถส่งrsyncรายการชื่อไฟล์ในอินพุตมาตรฐาน เนื่องจากrsyncคาดว่าจะมีรายการรูปแบบและไม่ใช่รายการชื่อไฟล์สิ่งนี้ต้องการให้ชื่อไฟล์ของคุณไม่มีอักขระไวด์การ์ด (โดยเฉพาะไม่มีการขึ้นบรรทัดใหม่ไม่มี\[*?และไม่มีชื่อเริ่มต้น#หรือ;)

svn st | awk '{print $2}' |
rsync -a --include-from=- --exclude='*' . my_name@my_server:~/
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.