سؤال

لقد قمت بإنشاء برنامج يتكرر على مجموعة من الملفات ويستدعي بعضها:

scp <file> user@host:<remotefile>

ومع ذلك، في حالتي، قد يكون هناك الآلاف من الملفات الصغيرة التي تحتاج إلى النقل، ويقوم scp بفتح اتصال ssh جديد لكل منها، الأمر الذي ينطوي على بعض الحمل الزائد.

كنت أتساءل عما إذا كان لا يوجد حل حيث أحافظ على تشغيل عملية واحدة تحافظ على الاتصال ويمكنني إرسال "طلبات" للنسخ عبر ملفات فردية.

من الناحية المثالية، أبحث عن مجموعة من برامج المرسل والمستقبل، بحيث يمكنني بدء عملية واحدة (1) في البداية:

ssh user@host receiverprogram

ولكل ملف، أقوم باستدعاء الأمر (2):

senderprogram <file> <remotefile>

وقم بتوصيل مخرج (2) إلى مدخل (1)، وهذا من شأنه أن يتسبب في نقل الملف.في النهاية، يمكنني فقط إرسال إشارة معينة للإنهاء للعملية (1).

ويفضل أن تكون برامج المرسل والمستقبل برامج C مفتوحة المصدر لنظام Unix.وقد يتواصلون باستخدام مقبس بدلاً من الأنبوب، أو أي حل إبداعي آخر.

ومع ذلك، فهو قيد مهم أن يتم نقل كل ملف في اللحظة التي أكرر فيها:ليس من المقبول جمع قائمة بالملفات ثم استدعاء مثيل واحد منها scp لنقل جميع الملفات مرة واحدة في النهاية.أيضًا، ليس لدي سوى وصول بسيط إلى المضيف المتلقي.

تحديث: لقد وجدت حلاً لمشكلة حمل الاتصال باستخدام ميزات تعدد الإرسال في ssh، راجع إجابتي الخاصة أدناه.ومع ذلك، فقد بدأت في إنشاء مكافأة لأنني أشعر بالفضول لمعرفة ما إذا كان هناك برنامج مرسل/مستقبل كما أصفه هنا.يبدو أنه يجب أن يكون هناك شيء يمكن استخدامه، على سبيل المثال.xmodem/ymodem/zmodem؟

هل كانت مفيدة؟

المحلول

قد تنجح هذه الطريقة، وبالنسبة لأشياء أخرى، فإن هذا النهج العام هو الصحيح إلى حد ما.

(
iterate over file list
  for each matching file
   echo filename
) | cpio -H newc -o | ssh remotehost cd location \&\& | cpio -H newc -imud

نصائح أخرى

لقد وجدت الحل من زاوية أخرى.منذ الإصدار 3.9, ، يدعم OpenSSH مضاعفة الجلسة:يمكن أن يحمل اتصال واحد عدة جلسات تسجيل دخول أو نقل ملفات.وهذا يتجنب تكلفة الإعداد لكل اتصال.

بالنسبة لحالة السؤال، يمكنني أولاً فتح اتصال من خلال إعداد عنصر التحكم الرئيسي (-M) مع مأخذ (-S) في مكان محدد.لا أحتاج إلى جلسة (-N).

ssh user@host -M -S /tmp/%r@%h:%p -N

بعد ذلك، يمكنني الاستدعاء scp لكل ملف وإرشاده لاستخدام نفس المقبس:

scp -o 'ControlPath /tmp/%r@%h:%p' <file> user@host:<remotefile>

يبدأ هذا الأمر في النسخ على الفور تقريبًا!

يمكنك أيضًا استخدام مقبس التحكم لاتصالات ssh العادية، والتي سيتم فتحها على الفور:

ssh user@host -S /tmp/%r@%h:%p

إذا لم يعد مقبس التحكم متاحًا (على سبيل المثال.لأنك قتلت السيد)، فهذا يعود إلى الاتصال الطبيعي.مزيد من المعلومات متاحة في هذا المقال.

قد يكون من المفيد استخدام sftp بدلاً من scp، ووضعه في الوضع الدفعي.اجعل ملف الأمر الدفعي عبارة عن أنبوب أو مقبس مجال UNIX وأوامر التغذية إليه كما تريد تنفيذها.

قد يكون الأمان في هذا الأمر صعبًا بعض الشيء من جانب العميل.

هل جربت sshfs؟يمكنك:

sshfs remote_user@remote_host:/remote_dir /mnt/local_dir

أين

  • /remote_dir كان هو الدليل الذي تريد إرسال الملفات إليه على النظام الذي تنتقل إليه
  • /mnt/local_dir كان موقع التثبيت المحلي

مع هذا الإعداد يمكنك فقط cp ملف في local_dir وسيتم إرسالها sftp ل remote_host فيه remote_dir

لاحظ أن هناك اتصالًا واحدًا، لذلك لا يوجد سوى القليل من الحمل

قد تحتاج إلى استخدام العلم -o ServerAliveInterval=15 للحفاظ على اتصال غير محدد

سوف تحتاج إلى أن يكون لديك fuse تم تثبيته محليًا ودعم خادم SSH (وتكوينه من أجل) sftp

ربما كنت تبحث عن هذا:ZSSH

zssh (Zmodem SSH) هو برنامج لنقل الملفات بشكل تفاعلي إلى جهاز بعيد أثناء استخدام الغلاف الآمن (ssh).الغرض منه هو أن يكون بديلاً مناسبًا لـ scp، مما يسمح بنقل الملفات دون الحاجة إلى فتح جلسة أخرى وإعادة المصادقة.

استخدم rsync عبر ssh إذا كان بإمكانك جمع كل الملفات لإرسالها في دليل واحد (أو التسلسل الهرمي للأدلة).

إذا لم يكن لديك جميع الملفات في مكان واحد، فيرجى تقديم بعض المعلومات الإضافية حول ما تريد تحقيقه ولماذا لا يمكنك تجميع جميع الملفات في الأرشيف وإرسالها.لماذا من المهم جدًا إرسال كل ملف على الفور؟هل سيكون من المقبول إذا تم إرسال الملف بتأخير قصير (مثلاً عند تراكم بيانات بقيمة 4K)؟

إنها مشكلة صغيرة لطيفة.لست على علم بوجود حل مُجهز مسبقًا، ولكن يمكنك فعل الكثير باستخدام نصوص shell البسيطة.سأحاول هذا على المتلقي:

#!/bin/ksh
# this is receiverprogram

while true
do
  typeset -i length
  read filename  # read filename sent by sender below
  read size      # read size of file sent
  read -N $size contents  # read all the bytes of the file
  print -n "$contents" > "$filename"
done

من جانب المرسل، أقوم بإنشاء أنبوب مسمى وأقرأ من الأنبوب، على سبيل المثال،

mkfifo $HOME/my-connection
ssh remotehost receiver-script < $HOME/my-connection

ثم لإرسال ملف سأجرب هذا البرنامج النصي

#!/bin/ksh
# this is senderprogram

FIFO=$HOME/my-connection

localname="$1"
remotename="$2"
print "$remotename" > $FIFO
size=$(stat -c %s "$localname")
print "$size" > $FIFO
cat "$localname" > $FIFO

إذا كان حجم الملف كبيرًا، فمن المحتمل أنك لا ترغب في قراءته مرة واحدة، لذا يجب أن يكون هناك شيء ما

BUFSIZ=8192

rm -f "$filename"
while ((size >= BUFSIZ)); do
  read -N $BUFSIZE buffer
  print -n "$buffer" >> "$filename"
  size=$((size - BUFSIZ))
done
read -N $size buffer
print -n "$contents" >> "$filename"

في النهاية ستحتاج إلى توسيع البرنامج النصي حتى تتمكن من المرور chmod و chgrp الأوامر.نظرًا لأنك تثق في رمز الإرسال، فقد يكون من الأسهل هيكلة الشيء بحيث يقوم المتلقي باستدعاء الصدفة ببساطة eval على كل سطر، ثم أرسل أشياء مثل

print filename='"'"$remotename"'"' > $FIFO
print "read_and_copy_bytes " '$filename' "$size" > $FIFO

ومن ثم تحديد وظيفة محلية read_and_copy_bytes.الحصول على الاقتباس الصحيح هو أمر دب، ولكن بخلاف ذلك يجب أن يكون واضحًا.

وبطبيعة الحال، لم يتم اختبار أي من هذا!ولكن آمل أن يعطيك بعض الأفكار المفيدة.

يبدو وكأنه وظيفة للقطران؟قم بتوصيل مخرجاته إلى ssh، وعلى الجانب الآخر قم بتوصيل مخرجات ssh مرة أخرى إلى tar.

أعتقد أن سطح مكتب جنوم يستخدم اتصال SSH واحدًا عند الوصول إلى مشاركة عبر SFTP (SSH).أعتقد أن هذا ما يحدث لأنني أرى عملية SSH واحدة عندما أقوم بالوصول إلى مشاركة عن بعد بهذه الطريقة.لذا، إذا كان هذا صحيحًا، فيجب أن تكون قادرًا على استخدام نفس البرنامج لهذا الغرض.

يستخدم الإصدار الجديد من جنوم GVFS من خلال جيو من أجل تنفيذ جميع أنواع الإدخال/الإخراج من خلال واجهات خلفية مختلفة.توفر حزمة Ubuntu gvfs-bin العديد من الأدوات المساعدة لسطر الأوامر التي تتيح لك التعامل مع الواجهات الخلفية من سطر الأوامر.

ستحتاج أولاً إلى تحميل مجلد SSH الخاص بك:

gvfs-mount sftp://user@host/

وبعد ذلك يمكنك استخدام نسخة gvfs لنسخ ملفاتك.أعتقد أنه سيتم تنفيذ جميع عمليات نقل الملفات من خلال عملية SSH واحدة.يمكنك حتى استخدام ps لمعرفة العملية التي يتم استخدامها.

إذا كنت تشعر بالمزيد من المغامرة، فيمكنك أيضًا كتابة برنامجك الخاص بلغة C أو بلغة أخرى عالية المستوى توفر واجهة برمجة التطبيقات لـ GIO.

خيار واحد هو محارة هو تطبيق عميل وخادم SSH مكتوب بلغة Python باستخدام ملتوي نطاق.يمكنك استخدامه لكتابة أداة تقبل الطلبات عبر بعض البروتوكولات الأخرى (مآخذ مجال HTTP أو Unix أو FTP أو SSH أو أي شيء آخر) وتقوم بتشغيل عمليات نقل الملفات عبر اتصال SSH طويل الأمد.في الواقع، لدي العديد من البرامج قيد الإنتاج التي تستخدم هذه التقنية لتجنب عمليات إعداد اتصال SSH المتعددة.

كان يوجد سؤال مشابه جدا هنا منذ أسبوعين.ال إجابة مقبولة يُقترح فتح نفق عند الاتصال بالجهاز البعيد واستخدام هذا النفق لعمليات نقل scp.

ربما CurlFTPFS قد يكون حلا صالحا بالنسبة لك.

يبدو أنه يقوم فقط بتثبيت مجلد كمبيوتر خارجي على جهاز الكمبيوتر الخاص بك عبر SFTP.بمجرد الانتهاء من ذلك، يجب أن تكون قادرًا على استخدام منتجك العادي cp الأوامر وكل شيء سيتم بشكل آمن.

لسوء الحظ لم أتمكن من اختباره بنفسي، ولكن اسمحوا لي أن أعرف إذا كان يعمل بالنسبة لك!

تحرير 1: لقد تمكنت من تنزيله واختباره.كما كنت أخشى أن الأمر يتطلب أن يكون لدى العميل خادم FTP. لكن, لقد وجدت برنامجًا آخر له نفس المفهوم تمامًا الذي تبحث عنه. sshfs يسمح لك بالاتصال بجهاز الكمبيوتر العميل الخاص بك دون الحاجة إلى أي خادم خاص.بمجرد قيامك بتثبيت أحد المجلدات الخاصة بهم، يمكنك استخدام الملف العادي cp أوامر لنقل أي ملفات تحتاجها أكثر.بمجرد الانتهاء من ذلك، ينبغي أن يكون الأمر ابتسامة umount /path/to/mounted/folder.اسمحوا لي أن أعرف كيف يعمل بها!

rsync -avlzp user@remotemachine:/path/to/files /path/to/this/folder

سيستخدم هذا SSH لنقل الملفات بطريقة غير بطيئة

اجعل الأمر بسيطًا، اكتب نصًا مجمعًا صغيرًا يفعل شيئًا كهذا.

  1. قطران الملفات
  2. أرسل ملف القطران
  3. untar على الجانب الآخر

شيء من هذا القبيل:

  1. ملفات tar -cvzf test.tgz ....
  2. scp test.tgz user@other.site.com:.
  3. ssh user@other.site.com tar -xzvf test.tgz

/جوهان

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top