Unix命令在服务器上工作,但不在ruby ssh会话中
我正在尝试学习如何使用net-ssh gem进行ruby。 在登录到目录 - / home / james后,我想执行下面的命令。
cd /
pwd
ls
当我用腻子做到这一点时,它可以工作,我可以看到目录列表。 但是,当我用ruby代码做它时,它不会给我相同的输出。
require 'rubygems'
require 'net/ssh'
host = 'server'
user = 'james'
pass = 'password123'
def get_ssh(host, user, pass)
ssh = nil
begin
ssh = Net::SSH.start(host, user, :password => pass)
puts "conn successful!"
rescue
puts "error - cannot connect to host"
end
return ssh
end
conn = get_ssh(host, user, pass)
def exec(linux_code, conn)
puts linux_code
result = conn.exec!(linux_code)
puts result
end
exec('cd /', conn)
exec('pwd', conn)
exec('ls', conn)
conn.close
输出 -
conn successful!
cd /
nil
pwd
/home/james
ls
nil
我期待pwd给我/而不是/ home / james。 这就是它在腻子中的工作原理。 Ruby代码中的错误是什么?
似乎每个命令都运行在它自己的环境中,所以当前目录不会从exec到exec。 如果你这样做,你可以验证这一点:
exec('cd / && pwd', conn)
它将打印/
。 从文档中不清楚如何使所有的命令在相同的环境中执行,或者甚至可以完成。
这是因为net/ssh
是无状态的,所以它会为每个命令执行打开一个新的连接。 您可以使用实现此功能的黑麦宝石。 但我不知道它是否适用于ruby> 2,因为它的发展并不那么活跃。
另一种方法是使用pty进程,在该进程中,您将使用ssh
命令打开一个伪终端,而不是使用输入和输出文件为终端编写命令并读取结果。 要读取结果,您需要使用IO类的select方法。 但是你需要学习如何使用这些工具,因为它对于一个没有经验的程序员来说并不那么明显。
而且,我发现了如何去做,事实上它非常简单。 我想我上次没有得到这个解决方案,因为我对net-ssh,pty终端这个东西有点新。 但是,我终于找到了它,并且在这里和范例中。
require 'net/ssh'
shell = {} #this will save the open channel so that we can use it accross threads
threads = []
# the shell thread
threads << Thread.new do
# Connect to the server
Net::SSH.start('localhost', 'your_user_name', password: 'your_password') do |session|
# Open an ssh channel
session.open_channel do |channel|
# send a shell request, this will open an interactive shell to the server
channel.send_channel_request "shell" do |ch, success|
if success
# Save the channel to be used in the other thread to send commands
shell[:ch] = ch
# Register a data event
# this will be triggered whenever there is data(output) from the server
ch.on_data do |ch, data|
puts data
end
end
end
end
end
end
# the commands thread
threads << Thread.new do
loop do
# This will prompt for a command in the terminal
print ">"
cmd = gets
# Here you've to make sure that cmd ends with 'n'
# since in this example the cmd is got from the user it ends with
#a trailing eol
shell[:ch].send_data cmd
# exit if the user enters the exit command
break if cmd == "exitn"
end
end
threads.each(&:join)
在这里,我们是一个使用net-ssh ruby gem的交互式终端。 欲了解更多信息,请查看它以前的版本1,但它对你了解每件作品的用途非常有用。 和这里
链接地址: http://www.djcxy.com/p/4309.html上一篇: Unix commands work on server but not in ruby ssh session