有什么方法可以使用 net-ssh 在 ruby 中获取登录 shell?这甚至可能吗?
通过登录外壳,我的意思是源 /etc/profile..
Net-SSH 的级别太低,无法简单地预先提供(无论如何都是现在的方式)。您可以查看基于 Net-SSH 构建的 Net-SSH-Shell 以添加登录 shell 功能:https ://github.com/mitchellh/net-ssh-shell
该实现是可靠的并且可以工作,但是我发现它不太有用,因为您无法专门提取诸如 stderr 或退出状态之类的内容,因为命令在子 shell 中运行,因此您只能获取 stdout。net-ssh-shell 库使用一些技巧来获取退出状态。
我自己的 Ruby 项目需要一个“登录 shell”,为此我通常使用以下代码直接在 shell 中执行操作:
def execute_in_shell!(commands, shell="bash")
channel = session.open_channel do |ch|
ch.exec("#{shell} -l") do |ch2, success|
# Set the terminal type
ch2.send_data "export TERM=vt100\n"
# Output each command as if they were entered on the command line
[commands].flatten.each do |command|
ch2.send_data "#{command}\n"
end
# Remember to exit or we'll hang!
ch2.send_data "exit\n"
# Configure to listen to ch2 data so you can grab stdout
end
end
# Wait for everything to complete
channel.wait
end
使用此解决方案,您仍然不会获得退出状态或命令的 stderr 运行到登录 shell,但至少命令是在该上下文中执行的。
我希望这有帮助。
现在有一种更好的方法可以做到这一点。相反,您可以使用带有 pty 的 shell 子系统来获取您期望从 shell 登录中获得的所有内容:
Net::SSH.start(@config.host, @config.user, :port => @config.port, :keys => @config.key, :config => true) do |session|
session.open_channel do |channel|
channel.request_pty
channel.send_channel_request "shell" do |ch, success|
if success
ch.send_data "env\n"
ch.send_data "#{command}\n"
ch.on_data do |c, data|
puts data
end
end
channel.send_data "exit\n"
channel.on_close do
puts "shell closed"
end
end
end
end
结尾