Как я могу выполнить 2 или более команды в той же сессии ssh?

У меня есть следующий script:

#!/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/

Ответ 1

посмотрите, есть ли что-то, аналогичное синтаксису блока cd (utils?), иначе просто запустите команду в той же подоболочке, например. ssh.exec "cd/var/example/engines/; pwd"?

Ответ 2

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

Это выполнит команду cd, а затем команду pwd в новом каталоге.

Я не рубиновый парень, но я собираюсь догадаться, что есть, вероятно, более элегантные решения.

Ответ 3

В Net:: SSH, #exec и #exec! совпадают, например. они выполняют команду (за исключением того, что exec! блокирует другие вызовы, пока это не будет выполнено). Главное, чтобы помнить, что Net:: SSH выполняет каждую команду из каталога пользователя при использовании exec/exec!. Итак, в вашем коде вы используете cd /some/path из каталога /root, а затем pwd - снова из каталога /root.

Самый простой способ, которым я знаю, как последовательно запускать несколько команд, - связать их вместе с && (как упоминалось выше другими плакатами). Таким образом, это будет выглядеть примерно так:

#!/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

К сожалению, служба оболочки Net:: SSH была удалена в версии 2.

Ответ 4

Вы можете просто дать разные команды, разделенные новой строкой. Что-то вроде:

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

Скорее всего, проще (и яснее) передать команду переменной, а затем передать переменную в exec. Тем не менее, тот же принцип.

Ответ 5

Я не рубиновый программист, но вы можете попытаться объединить свои команды; или && </p>

Ответ 6

Раньше существовала служба оболочки, которая позволяет выполнять команду stateful, как вы пытаетесь сделать в net/ssh v1, но она была удалена в v2. Однако есть побочный проект автора net/ssh, который позволяет вам это сделать. Посмотрите здесь: http://github.com/jamis/net-ssh-shell

Ответ 7

Изменено текущее местоположение net-ssh-shell.

То, что я решил использовать, чтобы вызвать случайную оболочку script, - это scp файл на удаленную машину и передать его в оболочку. В основном это: File.write(script_path, script_str) gear.ssh.scp_to(script_path, File.dirname(script_path)) gear.ssh.exec(". script_path")