如何在Ruby中使用net-ssh进行sudo su操作

6
我正在尝试弄清楚如何在Ruby中发送多个net-ssh命令链,以在sudo su - #{su_user}之后执行。
我的当前代码如下,在send_data "#{password}\n"之后,由于sudo su命令而挂起。
与此同时,在系统上,手动执行sudo su - admin2不需要输入密码。
任何帮助都将不胜感激!
require 'rubygems'  
require 'net/ssh'
host = 'hostA'

user = 'admin'
password = 'hostA_pwd'
su_user = 'Admin2'

Net::SSH.start(host, user, :password => password) do |ssh|

     ssh.open_channel do |channel|  
       channel.request_pty do |c, success|
         raise "could not request pty" unless success

         channel.exec "pwd; whoami; sudo su - #{su_user} ; pwd ; whoami"
         channel.on_data do |c_, data|
           if data =~ /\[sudo\]/ || data =~ /Password/i
             channel.send_data "#{password}\n"
           else       
             result << data
           end
         end
         puts result
       end
     end
     ssh.loop
  end

你知道在sudo命令之后不能像那样链接命令吗?最后的pwd; whoami命令将会在sudo命令shell返回之后才被执行。你考虑到这点了吗? - Casper
1个回答

3

sudo 支持 -c 选项,该选项将命令传递给子 shell。以下是一些可能对您有用的 sudo 标志:

-c, --command=COMMAND
      pass a single COMMAND to the shell with -c

--session-command=COMMAND
      pass a single COMMAND to the shell with -c and do not create a new session

-m, --preserve-environment
      do not reset environment variables

-s, --shell=SHELL
      run SHELL if /etc/shells allows it

因此,使用像 sudo su someuser -c 'ls;date' 这样的命令,您将以 someuser 的身份执行 lsdate 命令。在该主机上尝试一下命令行,了解您可以做些什么,然后将其应用于您的 SSH 会话。
有关更多信息,请参见 man sudo
另外,作为编码提示,您可以将以下内容简化:
if data =~ /\[sudo\]/ || data =~ /Password/i

to:

if (data[/\[sudo\]|Password/i])

感谢您的回复,我已按照Tin Man的建议在代码中修改了该行以包含-c选项。谢谢。<br /> channel.exec "pwd; whoami; sudo -u #{su_user} sh -c 'whoami ; cd /tmp ; pwd; ls'" - SysTest RJR
这是一个很好的技巧,在sudo su someuser下传递-c 'command'命令非常有效。那真是个好技巧。 - Jacob Waller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接