الرد على موجه SSH قبل الأمر الأول مع روبي والصافي :: SSH

StackOverflow https://stackoverflow.com/questions/2223194

  •  19-09-2019
  •  | 
  •  

سؤال

أحاول الاتصال باستخدام 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 يمكنك فتح قنوات متعددة. ربما يستجيب الخادم فقط إلى القناة الافتراضية الأولى وإذا فتحت واحدة أخرى تحصل على قذيفة جديدة.

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