الرد على موجه SSH قبل الأمر الأول مع روبي والصافي :: SSH
سؤال
أحاول الاتصال باستخدام Net :: SSH، إلى خادم مباشرة بعد تنفيذ البرنامج النصي يتطلب إدخال من المستخدم. يجب على المستخدم إدخال "1" أو "2" وستتلقى بعض البيانات عبر المحطة بعد ذلك.
مشكلتي هي أنه على الرغم من أنني قادر على الاتصال، لا أستطيع معرفة طريقة لإرسال "1 n" إلى الخادم واستلام الإخراج.
يتوقف التعليمة البرمجية التالية في "معلومات - net.ssh.connection.session [80906b74]: channel_open_confirmation: 0 0 0 32768".
باستخدام Channel.exec ("1 n") بدلا من القناة.send_data بشكل غير صحيح لا يعمل أيضا.
Net::SSH.start('host', 'user', :password => "pass", :auth_methods => ["password"], :verbose => :debug) do |session|
session.open_channel do |channel|
channel.on_data do |ch, data|
STDOUT.print data
end
channel.send_data( "1\n")
end
session.loop
end
أي أفكار، أي شخص؟
شكرا مقدما
المحلول
يمكنك التحقق من ذلك send_data
دعوة يحدث بعد تحصل على موجه من الخادم البعيد؟ حاول بناء أ channel.on_data
كتلة حولك send_data
اتصل بحيث يمكنك التحقق من أن تحصل على المطالبة المتوقعة عن الخادم قبل إرسال استجابة.
قد لا تريد أن تستخدم exec
هنا. من مستندات NET :: SSH :: Connection :: Channel:
يرسل طلب قناة يطلب استدعاء الأمر المحدد.
أنت تريد إرسال سلسلة نصية للرد على موجه، وليس استدعاء أمر. المستندات تظهر exec
يتم استخدامها لإرسال أوامر CLI كاملة مثل "LS -L / HOME".
في حين أن، send_data
ربما ما تريد. تظهر المستندات أنها تستخدم لإرسال نص تعسفي مثل channel.send_data("the password\n")
. وبعد ملاحظة، ومع ذلك، هذه الجملة في المستندات:
لاحظ أنه لا يرسل البيانات على الفور في جميع أنحاء القناة، ولكن بدلا من ذلك فقط إلحاق البيانات المعطاة إلى المخزن المؤقت الإخراج للقناة والتحضيري للتعبئة وإرسالها في المرة التالية التي يقبل فيها الاتصال البيانات.
قد ترغب في إلقاء نظرة على channel.request_pty
. وبعد يبدو أنه مصمم للتفاعل مع تطبيق يستند إلى وحدة التحكم.
إذا كنت تحاول (في جوهرها) البرنامج النصي جلسة SSH تقوم عادة يدويا، فقد تجد أنه من الأسهل استخدام expect
مثل واجهة (على سبيل المثال، جوهرة مثل sshexpect قد يكون يستحق المحاولة).
نصائح أخرى
شكرا لكم جميعا على المؤشرات. لقد تمكنت من وضع إصبعي على المشكلة - إلى جانب استخدام القناة. لقد كان من الضروري أيضا طلب قذيفة. ما يلي يعمل أخيرا كما هو متوقع:
Net::SSH.start('host', 'user', :password => "pass", :auth_methods => ["password"]) do |session|
session.open_channel do |channel|
channel.request_pty do |ch, success|
raise "Error requesting pty" unless success
ch.send_channel_request("shell") do |ch, success|
raise "Error opening shell" unless success
end
end
channel.on_data do |ch, data|
STDOUT.print data
end
channel.on_extended_data do |ch, type, data|
STDOUT.print "Error: #{data}\n"
end
channel.send_data( "1\n" )
session.loop
end
end
أنا لست على دراية رهيبة بالشبكة :: SSH Libs حتى لا يمكنني المساعدة في ذلك كل أسبوع ولكن يبدو أنك يمكن أن تحقق ما تريد استخدامه Capistrano..
على سبيل المثال، لدي مهمة Capistrano التي تتصل بخادم بعيد، ويتم تشغيل أمر يتوقع الإدخال ثم يستمر. Capistrano تعتني بعيد I / O. ربما يمكن أن يكون ذلك حلا بالنسبة لك؟
آمل أن يساعد!
إذا قمت بالتنفيذ "1\n"
في قذيفة الرد أحصل عليه هو: bash: 1: command not found
إذا قمت بالتنفيذ echo "1"
انا حصلت: 1
هل أنت متأكد أنك تريد محاولة تنفيذ النص الذي ترسله؟ ربما كنت تبحث عن شيء مثل:
output = ""
Net::SSH.start('host', 'user', :password => "pass") do |ssh|
output = ssh.exec! "echo 1"
end
puts output
أنا لست بارزا من هذا Lib، ولكن على SSH يمكنك فتح قنوات متعددة. ربما يستجيب الخادم فقط إلى القناة الافتراضية الأولى وإذا فتحت واحدة أخرى تحصل على قذيفة جديدة.