2010-07-28 23 views
5

मैं थोर का उपयोग करके एक छोटी लाइब्रेरी लिखने की कोशिश कर रहा हूं ताकि नई परियोजनाओं और साइटों को त्वरित बनाने में मेरी सहायता कर सकूं। मैंने इस छोटी विधि को लिखा:नेट :: एसएसएच सुडो कमांड पासवर्ड दर्ज करने के बाद लटकता है

def ssh(cmd) 
    Net::SSH.start(server_ip, user, :port => port) do |session| 
    session.exec cmd 
    end 
end 

बस आवश्यकता होने पर दूरस्थ सर्वर पर त्वरित आदेश चलाने में मेरी सहायता करने के लिए।

समस्या तब होती है जब मुझे रिमोट एंड पर सुडो के तहत कमांड चलाने की आवश्यकता होती है, तो स्क्रिप्ट बस मुझ पर लटका लगती है। उदाहरण के लिए जब यह क्रियान्वित ...

ssh("sudo cp #{file_from_path} #{file_to_path}") 

स्क्रिप्ट पूरी बात hhangs में यह लिखने के बाद पासवर्ड

[sudo] password for user: 

के लिए मुझे संकेत देगा लेकिन तब।

किसी को पता क्या होगा यह वास्तव में क्यों लटका है, और नेट :: एसएसएच (या कुछ वैकल्पिक) के तहत रिमोट सर्वर पर सुडो कमांड चलाने के लिए मैं क्या कर सकता हूं?

* नोट: सुझाव देने से पहले, मैंने मूल रूप से कैपिस्ट्रानो के तहत एक नुस्खा के रूप में इस पुस्तकालय को लिखना शुरू कर दिया था, जब तक कि मैं थोर पर नहीं आया, और सोचा कि यह कोशिश करने का एक अच्छा मौका होगा। यदि आवश्यक हो तो मैं पूरी चीज को कैपिस्ट्रानो पर वापस स्विच करने के खिलाफ नहीं हूं, लेकिन अगर मैं रिमोट सर्वर पर सुडो कमांड चलाने का कोई आसान तरीका नहीं हूं तो मैं वास्तव में आश्चर्यचकित हूं।

+0

क्या आप पासवर्ड पाइप करने में सक्षम हैं? 'ssh (" sudo cp # {from} # {to} <"mysupass") ' – Fosco

+0

बेशक मैं पिछली टिप्पणी में डबल कोट्स से बचने के लिए भूल गया था। – Fosco

+0

कोशिश की, लेकिन यह काम नहीं करता है। यह वापस आ गया है "bash: mysupass: ऐसी कोई फ़ाइल या निर्देशिका नहीं है।" क्या यह प्रॉम्प्ट के माध्यम से पासवर्ड को पाइप करने का प्रयास है? यदि ऐसा है, तो विचार काम कर सकता है, लेकिन सिंटैक्स शायद बंद है। मैं देखता हूं कि मुझे क्या मिल सकता है कि – joeellis

उत्तर

1

पहली चीज़ जो आप कोशिश करना चाहें, लॉगिन के बजाय पासवर्ड की बजाय सार्वजनिक कुंजी का उपयोग कर रही है। फिर इंटरैक्टिव शैल से कमांड चलाने का भी प्रयास करें।

उदाहरण के लिए:

(इस भाग वास्तव में सर्वर/क्लाइंट सॉफ्टवेयर आप पर निर्भर करता है)

$ ssh-keygen 
$ scp .ssh/id-dsa.pub server: 
$ ssh server 
server$ cat id-dsa.pub >> .ssh/authorizedkeys 

$ scp -c "ls" 

इस, किसी भी संकेत के बिना काम करना चाहिए अगर कुंजी बंटवारे सफल रहा था।

+1

असल में मैं सार्वजनिक कुंजी का उपयोग कर रहा हूं। पासवर्ड जो एसएसएच कनेक्शन के लिए पासवर्ड नहीं है, लेकिन कमांड को कमांड चलाने के लिए पासवर्ड है। इसलिए मुझे कम से कम यह पता चलता है कि यह कनेक्ट हो जाता है, लेकिन भरने के बाद यह लटकता है sudo पासवर्ड। – joeellis

+0

आप विशिष्ट उपयोगकर्ता के लिए पासवर्ड मांगने के लिए सूडो सेट करने का प्रयास कर सकते हैं। – sukru

+0

मैंने अंत में अनुयायी लाइनों को जोड़कर रिमोट सर्वर पर सूडोर्स फ़ाइल में यह कोशिश की थी "उपयोगकर्ता ALL = (ALL) ALL ", लेकिन मुझे अभी भी संकेत मिल रहा है। क्या मैं वें कर रहा हूं गलत है? – joeellis

4

यह सेट अप करने के लिए net/ssh के साथ संभव है, लेकिन यह वास्तव में बहुत ज्यादा प्रयास है, बस इस तरह ssh आदेश निष्पादित करें:

system("ssh", "-t", "#{user}@#{host}", "sudo cp #{file_from_path} #{file_to_path}") 

यह -t एक tty आवंटित करने के लिए इसका मतलब है। इसके बिना यह अभी भी काम करेगा, लेकिन आपका पासवर्ड स्पष्ट रूप से देखा जाएगा।

(मुझे लगता है कि आप मैन्युअल रूप से सुडो पासवर्ड टाइप करना चाहते हैं। यदि नहीं, तो अधिकृत कुंजी के रास्ते पर जाएं)।

5

यहाँ एक संभव समाधान है:

def ssh(cmd) 
    Net::SSH.start(server_ip, user, :port => port) do |session| 
    result = nil 
    session.exec!(cmd) do |channel, stream, data| 
     if data =~ /^\[sudo\] password for user:/ 
     channel.send_data 'your_sudo_password' 
     else 
     result << data 
     end 
    end 
    result # content of 'cmd' result 
    end 
end 

लेकिन इस समाधान के साथ, आप अपने रूट पासवर्ड एक स्क्रिप्ट फ़ाइल कहीं में स्पष्ट में लिखा है ...

+0

@japancheese आपके द्वारा पोस्ट किया गया अंतिम कोड सुडो प्रॉम्प्ट पासवर्ड को संभाल नहीं करता है। यह आपके प्रश्न में बिल्कुल वही कोड दिया गया है। – Riba

-1
अंत में वास्तव में

, मैं कुछ किया बहुत रीबा के सुझाव के समान (हालांकि उसकी/उसके कोड काफी बेहतर और होशियार है, मुझे लगता है)

def ssh(env, cmd, opts={}) 
    Net::SSH.start(config[env]["ip"], config[env]["user"], :port => config[env]["port"]) do |session| 
     cmd = "sudo #{cmd}" if opts[:sudo] 
     print cmd 
     session.exec cmd 
    end 
end 
13

मुझे आशा है कि यह किसी को खोज में मदद मिलेगी।(पतली उदाहरणों को पुन: प्रारंभ) मैं भी तैनाती के दौरान sudo करने की जरूरत

# deploy.rake 
require 'net/ssh' 

# INITIALIZE CONSTANTS HERE 
HOST = 'yourwebsite.com' 
USER = 'admin' 
PASSWORD = 'your server password' # or use ENV variables? 
# etc. 

namespace :deploy do 
    namespace :staging do 
    task :restart do 
     commands = [ 
     "cd #{PATH_TO_STAGING_APP} && git checkout master", 
     "git reset --hard HEAD", 
     "git pull origin master", 
     "bundle install --without test development", 
     "sudo thin restart -C /etc/thin/#{STAGING_APP}.yml" 
     ] 

     Net::SSH.start(HOST, USER, :password => PASSWORD) do |ssh| 
     ssh.open_channel do |channel| 
      channel.request_pty do |ch, success| 
      if success 
       puts "Successfully obtained pty" 
      else 
       puts "Could not obtain pty" 
      end 
      end 

      channel.exec(commands.join(';')) do |ch, success| 
      abort "Could not execute commands!" unless success 

      channel.on_data do |ch, data| 
       puts "#{data}" 
       channel.send_data "#{PASSWORD}\n" if data =~ /password/ 
      end 

      channel.on_extended_data do |ch, type, data| 
       puts "stderr: #{data}" 
      end 

      channel.on_close do |ch| 
       puts "Channel is closing!" 
      end 
      end 
     end 
     ssh.loop 
     end 
    end 
    end 
end 

ध्यान दें कि एक चैनल केवल एक ही आदेश पर अमल कर सकते हैं। इसलिए मैं commands.join(';') के साथ एक साथ आदेशों श्रृंखलित

संदर्भ: इस जोड़ने करके Net::SSH::Connection::Channel

2

मैं धोखा दिया:

sudouser ALL=(ALL:ALL) NOPASSWD: ALL 

/etc/sudoers

लिए इसके अलावा, जब संपादन visudo का उपयोग सुनिश्चित करें !! !