如何在同一个ssh会话中执行2个或更多命令?

时间:2010-09-08 19:55:18

标签: ruby

我有以下脚本:

#!/usr/bin/env ruby
require 'rubygems'
require 'net/ssh'

Net::SSH.start('host1', 'root', :password => "mypassword1") do |ssh|
    stdout = ""

    ssh.exec("cd /var/example/engines/")
    ssh.exec!( "pwd" ) do |channel, stream, data|
        stdout << data if stream == :stdout
    end
    puts stdout

    ssh.loop
end

我获得了/root,而不是/var/example/engines/

7 个答案:

答案 0 :(得分:2)

ssh.exec("cd /var/example/engines/; pwd")

这将执行cd命令,然后执行新目录中的pwd命令。

我不是一个红宝石的家伙,但我猜可能会有更优雅的解决方案。

答案 1 :(得分:2)

在Net :: SSH中,#exec&amp; #exec!是相同的,例如它们执行一个命令(exec!阻止其他调用的例外情况,直到它完成)。要记住的关键是Net :: SSH本质上在使用exec / exec时运行用户目录中的每个命令。因此,在您的代码中,您从cd /some/path目录运行/root,然后再从pwd目录运行/root

我知道如何按顺序运行多个命令的最简单方法是将它们与&amp;&amp; (如上面其他海报所述)。所以,它看起来像这样:

#!/usr/bin/env ruby
require 'rubygems'
require 'net/ssh'

Net::SSH.start('host1', 'root', :password => "mypassword1") do |ssh|
    stdout = ""

    ssh.exec!( "cd /var/example/engines/ && pwd" ) do |channel, stream, data|
        stdout << data if stream == :stdout
    end
    puts stdout

    ssh.loop
end

不幸的是,版本2中删除了Net :: SSH shell service

答案 2 :(得分:2)

您可以使用新行分隔不同的命令。类似的东西:

@result = ssh.exec!("cd /var/example/engines/
                    pwd
                   ")
puts @result

将命令传递给变量可能更容易(也更清晰),然后将变量传递给exec。同样的原则。

答案 3 :(得分:1)

我不是一个红宝石程序员,但你可以尝试连接你的命令;或&amp;&amp;

答案 4 :(得分:1)

看看是否有类似于文件(utils?)cd块语法的东西,否则只需在相同的子shell中运行命令,例如ssh.exec“cd / var / example / engines /; pwd”?

答案 5 :(得分:1)

曾经有一个shell服务允许有状态的命令,就像你试图在net / ssh v1中做的那样,但它已经在v2中删除了。然而,net / ssh的作者有一个侧面项目允许你这样做。看看这里:http://github.com/jamis/net-ssh-shell

答案 6 :(得分:0)

net-ssh-shell is changed.

的当前位置

我决定使用随机shell脚本调用的方法是将文件scp到远程计算机并将其导入shell。基本上这样做: File.write(script_path, script_str) gear.ssh.scp_to(script_path, File.dirname(script_path)) gear.ssh.exec(". script_path")